Add coreView state in FE (#14034)

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
This commit is contained in:
Weiko
2025-08-25 15:49:21 +02:00
committed by GitHub
parent 293cf0be39
commit dff00e813c
21 changed files with 441 additions and 204 deletions
@@ -4653,7 +4653,7 @@ export type ViewFilterFragmentFragment = { __typename?: 'CoreViewFilter', id: st
export type ViewFilterGroupFragmentFragment = { __typename?: 'CoreViewFilterGroup', id: string, parentViewFilterGroupId?: string | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: string, createdAt: string, updatedAt: string };
export type ViewFragmentFragment = { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null };
export type ViewFragmentFragment = { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: string, fieldMetadataId: string, viewId: string, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: string, fieldMetadataId: string, operand: ViewFilterOperand, value: any, viewFilterGroupId?: string | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: string, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: string, parentViewFilterGroupId?: string | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: string, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: string, fieldMetadataId: string, direction: ViewSortDirection, viewId: string, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: string, fieldMetadataId: string, isVisible: boolean, fieldValue: string, position: number, viewId: string, createdAt: string, updatedAt: string }> };
export type ViewGroupFragmentFragment = { __typename?: 'CoreViewGroup', id: string, fieldMetadataId: string, isVisible: boolean, fieldValue: string, position: number, viewId: string, createdAt: string, updatedAt: string };
@@ -4664,7 +4664,7 @@ export type CreateCoreViewMutationVariables = Exact<{
}>;
export type CreateCoreViewMutation = { __typename?: 'Mutation', createCoreView: { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null } };
export type CreateCoreViewMutation = { __typename?: 'Mutation', createCoreView: { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: string, fieldMetadataId: string, viewId: string, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: string, fieldMetadataId: string, operand: ViewFilterOperand, value: any, viewFilterGroupId?: string | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: string, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: string, parentViewFilterGroupId?: string | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: string, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: string, fieldMetadataId: string, direction: ViewSortDirection, viewId: string, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: string, fieldMetadataId: string, isVisible: boolean, fieldValue: string, position: number, viewId: string, createdAt: string, updatedAt: string }> } };
export type CreateCoreViewFieldMutationVariables = Exact<{
input: CreateViewFieldInput;
@@ -4791,7 +4791,7 @@ export type UpdateCoreViewMutationVariables = Exact<{
}>;
export type UpdateCoreViewMutation = { __typename?: 'Mutation', updateCoreView: { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null } };
export type UpdateCoreViewMutation = { __typename?: 'Mutation', updateCoreView: { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: string, fieldMetadataId: string, viewId: string, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: string, fieldMetadataId: string, operand: ViewFilterOperand, value: any, viewFilterGroupId?: string | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: string, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: string, parentViewFilterGroupId?: string | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: string, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: string, fieldMetadataId: string, direction: ViewSortDirection, viewId: string, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: string, fieldMetadataId: string, isVisible: boolean, fieldValue: string, position: number, viewId: string, createdAt: string, updatedAt: string }> } };
export type UpdateCoreViewFieldMutationVariables = Exact<{
id: Scalars['String'];
@@ -4873,14 +4873,14 @@ export type FindManyCoreViewsQueryVariables = Exact<{
}>;
export type FindManyCoreViewsQuery = { __typename?: 'Query', getCoreViews: Array<{ __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null }> };
export type FindManyCoreViewsQuery = { __typename?: 'Query', getCoreViews: Array<{ __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: string, fieldMetadataId: string, viewId: string, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: string, fieldMetadataId: string, operand: ViewFilterOperand, value: any, viewFilterGroupId?: string | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: string, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: string, parentViewFilterGroupId?: string | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: string, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: string, fieldMetadataId: string, direction: ViewSortDirection, viewId: string, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: string, fieldMetadataId: string, isVisible: boolean, fieldValue: string, position: number, viewId: string, createdAt: string, updatedAt: string }> }> };
export type FindOneCoreViewQueryVariables = Exact<{
id: Scalars['String'];
}>;
export type FindOneCoreViewQuery = { __typename?: 'Query', getCoreView?: { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null } | null };
export type FindOneCoreViewQuery = { __typename?: 'Query', getCoreView?: { __typename?: 'CoreView', id: string, name: string, objectMetadataId: string, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: string | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: string, fieldMetadataId: string, viewId: string, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: string, fieldMetadataId: string, operand: ViewFilterOperand, value: any, viewFilterGroupId?: string | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: string, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: string, parentViewFilterGroupId?: string | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: string, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: string, fieldMetadataId: string, direction: ViewSortDirection, viewId: string, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: string, fieldMetadataId: string, isVisible: boolean, fieldValue: string, position: number, viewId: string, createdAt: string, updatedAt: string }> } | null };
export type FindOneCoreViewFieldQueryVariables = Exact<{
id: Scalars['String'];
@@ -5256,24 +5256,6 @@ export const RoleFragmentFragmentDoc = gql`
canDestroyAllObjectRecords
}
`;
export const ViewFragmentFragmentDoc = gql`
fragment ViewFragment on CoreView {
id
name
objectMetadataId
type
key
icon
position
isCompact
openRecordIn
kanbanAggregateOperation
kanbanAggregateOperationFieldMetadataId
createdAt
updatedAt
anyFieldFilterValue
}
`;
export const ViewFieldFragmentFragmentDoc = gql`
fragment ViewFieldFragment on CoreViewField {
id
@@ -5334,6 +5316,43 @@ export const ViewGroupFragmentFragmentDoc = gql`
updatedAt
}
`;
export const ViewFragmentFragmentDoc = gql`
fragment ViewFragment on CoreView {
id
name
objectMetadataId
type
key
icon
position
isCompact
openRecordIn
kanbanAggregateOperation
kanbanAggregateOperationFieldMetadataId
createdAt
updatedAt
anyFieldFilterValue
viewFields {
...ViewFieldFragment
}
viewFilters {
...ViewFilterFragment
}
viewFilterGroups {
...ViewFilterGroupFragment
}
viewSorts {
...ViewSortFragment
}
viewGroups {
...ViewGroupFragment
}
}
${ViewFieldFragmentFragmentDoc}
${ViewFilterFragmentFragmentDoc}
${ViewFilterGroupFragmentFragmentDoc}
${ViewSortFragmentFragmentDoc}
${ViewGroupFragmentFragmentDoc}`;
export const AvailableWorkspaceFragmentFragmentDoc = gql`
fragment AvailableWorkspaceFragment on AvailableWorkspace {
id
@@ -5454,21 +5473,6 @@ export const UserQueryFragmentFragmentDoc = gql`
isTwoFactorAuthenticationEnforced
views {
...ViewFragment
viewFields {
...ViewFieldFragment
}
viewFilters {
...ViewFilterFragment
}
viewFilterGroups {
...ViewFilterGroupFragment
}
viewSorts {
...ViewSortFragment
}
viewGroups {
...ViewGroupFragment
}
}
}
availableWorkspaces {
@@ -5482,11 +5486,6 @@ ${ObjectPermissionFragmentFragmentDoc}
${WorkspaceUrlsFragmentFragmentDoc}
${RoleFragmentFragmentDoc}
${ViewFragmentFragmentDoc}
${ViewFieldFragmentFragmentDoc}
${ViewFilterFragmentFragmentDoc}
${ViewFilterGroupFragmentFragmentDoc}
${ViewSortFragmentFragmentDoc}
${ViewGroupFragmentFragmentDoc}
${AvailableWorkspacesFragmentFragmentDoc}`;
export const AssignRoleToAgentDocument = gql`
mutation AssignRoleToAgent($agentId: UUID!, $roleId: UUID!) {
+47 -28
View File
@@ -3596,7 +3596,7 @@ export type ViewFilterFragmentFragment = { __typename?: 'CoreViewFilter', id: an
export type ViewFilterGroupFragmentFragment = { __typename?: 'CoreViewFilterGroup', id: any, parentViewFilterGroupId?: any | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: any, createdAt: string, updatedAt: string };
export type ViewFragmentFragment = { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null };
export type ViewFragmentFragment = { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: any, fieldMetadataId: any, viewId: any, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: any, fieldMetadataId: any, operand: ViewFilterOperand, value: any, viewFilterGroupId?: any | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: any, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: any, parentViewFilterGroupId?: any | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: any, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: any, fieldMetadataId: any, direction: ViewSortDirection, viewId: any, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: any, fieldMetadataId: any, isVisible: boolean, fieldValue: string, position: number, viewId: any, createdAt: string, updatedAt: string }> };
export type ViewGroupFragmentFragment = { __typename?: 'CoreViewGroup', id: any, fieldMetadataId: any, isVisible: boolean, fieldValue: string, position: number, viewId: any, createdAt: string, updatedAt: string };
@@ -3607,7 +3607,7 @@ export type CreateCoreViewMutationVariables = Exact<{
}>;
export type CreateCoreViewMutation = { __typename?: 'Mutation', createCoreView: { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null } };
export type CreateCoreViewMutation = { __typename?: 'Mutation', createCoreView: { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: any, fieldMetadataId: any, viewId: any, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: any, fieldMetadataId: any, operand: ViewFilterOperand, value: any, viewFilterGroupId?: any | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: any, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: any, parentViewFilterGroupId?: any | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: any, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: any, fieldMetadataId: any, direction: ViewSortDirection, viewId: any, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: any, fieldMetadataId: any, isVisible: boolean, fieldValue: string, position: number, viewId: any, createdAt: string, updatedAt: string }> } };
export type CreateCoreViewFieldMutationVariables = Exact<{
input: CreateViewFieldInput;
@@ -3734,7 +3734,7 @@ export type UpdateCoreViewMutationVariables = Exact<{
}>;
export type UpdateCoreViewMutation = { __typename?: 'Mutation', updateCoreView: { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null } };
export type UpdateCoreViewMutation = { __typename?: 'Mutation', updateCoreView: { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: any, fieldMetadataId: any, viewId: any, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: any, fieldMetadataId: any, operand: ViewFilterOperand, value: any, viewFilterGroupId?: any | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: any, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: any, parentViewFilterGroupId?: any | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: any, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: any, fieldMetadataId: any, direction: ViewSortDirection, viewId: any, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: any, fieldMetadataId: any, isVisible: boolean, fieldValue: string, position: number, viewId: any, createdAt: string, updatedAt: string }> } };
export type UpdateCoreViewFieldMutationVariables = Exact<{
id: Scalars['String'];
@@ -3816,14 +3816,14 @@ export type FindManyCoreViewsQueryVariables = Exact<{
}>;
export type FindManyCoreViewsQuery = { __typename?: 'Query', getCoreViews: Array<{ __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null }> };
export type FindManyCoreViewsQuery = { __typename?: 'Query', getCoreViews: Array<{ __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: any, fieldMetadataId: any, viewId: any, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: any, fieldMetadataId: any, operand: ViewFilterOperand, value: any, viewFilterGroupId?: any | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: any, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: any, parentViewFilterGroupId?: any | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: any, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: any, fieldMetadataId: any, direction: ViewSortDirection, viewId: any, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: any, fieldMetadataId: any, isVisible: boolean, fieldValue: string, position: number, viewId: any, createdAt: string, updatedAt: string }> }> };
export type FindOneCoreViewQueryVariables = Exact<{
id: Scalars['String'];
}>;
export type FindOneCoreViewQuery = { __typename?: 'Query', getCoreView?: { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null } | null };
export type FindOneCoreViewQuery = { __typename?: 'Query', getCoreView?: { __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, createdAt: string, updatedAt: string, anyFieldFilterValue?: string | null, viewFields: Array<{ __typename?: 'CoreViewField', id: any, fieldMetadataId: any, viewId: any, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: any, fieldMetadataId: any, operand: ViewFilterOperand, value: any, viewFilterGroupId?: any | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: any, createdAt: string, updatedAt: string }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: any, parentViewFilterGroupId?: any | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: any, createdAt: string, updatedAt: string }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: any, fieldMetadataId: any, direction: ViewSortDirection, viewId: any, createdAt: string, updatedAt: string }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: any, fieldMetadataId: any, isVisible: boolean, fieldValue: string, position: number, viewId: any, createdAt: string, updatedAt: string }> } | null };
export type FindOneCoreViewFieldQueryVariables = Exact<{
id: Scalars['String'];
@@ -3898,6 +3898,28 @@ export const ViewFilterGroupFragmentFragmentDoc = gql`
updatedAt
}
`;
export const ViewSortFragmentFragmentDoc = gql`
fragment ViewSortFragment on CoreViewSort {
id
fieldMetadataId
direction
viewId
createdAt
updatedAt
}
`;
export const ViewGroupFragmentFragmentDoc = gql`
fragment ViewGroupFragment on CoreViewGroup {
id
fieldMetadataId
isVisible
fieldValue
position
viewId
createdAt
updatedAt
}
`;
export const ViewFragmentFragmentDoc = gql`
fragment ViewFragment on CoreView {
id
@@ -3914,30 +3936,27 @@ export const ViewFragmentFragmentDoc = gql`
createdAt
updatedAt
anyFieldFilterValue
viewFields {
...ViewFieldFragment
}
viewFilters {
...ViewFilterFragment
}
viewFilterGroups {
...ViewFilterGroupFragment
}
viewSorts {
...ViewSortFragment
}
viewGroups {
...ViewGroupFragment
}
}
`;
export const ViewGroupFragmentFragmentDoc = gql`
fragment ViewGroupFragment on CoreViewGroup {
id
fieldMetadataId
isVisible
fieldValue
position
viewId
createdAt
updatedAt
}
`;
export const ViewSortFragmentFragmentDoc = gql`
fragment ViewSortFragment on CoreViewSort {
id
fieldMetadataId
direction
viewId
createdAt
updatedAt
}
`;
${ViewFieldFragmentFragmentDoc}
${ViewFilterFragmentFragmentDoc}
${ViewFilterGroupFragmentFragmentDoc}
${ViewSortFragmentFragmentDoc}
${ViewGroupFragmentFragmentDoc}`;
export const SearchDocument = gql`
query Search($searchInput: String!, $limit: Int!, $after: String, $excludedObjectNameSingulars: [String!], $includedObjectNameSingulars: [String!], $filter: ObjectRecordFilterInput) {
search(
@@ -1,5 +1,6 @@
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { coreViewsState } from '@/views/states/coreViewState';
import { ViewKey } from '@/views/types/ViewKey';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { selectorFamily } from 'recoil';
export const prefetchIndexViewIdFromObjectMetadataItemFamilySelector =
@@ -8,7 +9,9 @@ export const prefetchIndexViewIdFromObjectMetadataItemFamilySelector =
get:
({ objectMetadataItemId }) =>
({ get }) => {
const views = get(prefetchViewsState);
const coreViews = get(coreViewsState);
const views = coreViews.map(convertCoreViewToView);
return views?.find(
(view) =>
view.objectMetadataId === objectMetadataItemId &&
@@ -1,5 +1,6 @@
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { coreViewsState } from '@/views/states/coreViewState';
import { type View } from '@/views/types/View';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { selectorFamily } from 'recoil';
export const prefetchViewFromViewIdFamilySelector = selectorFamily<
@@ -10,7 +11,9 @@ export const prefetchViewFromViewIdFamilySelector = selectorFamily<
get:
({ viewId }) =>
({ get }) => {
const views = get(prefetchViewsState);
const coreViews = get(coreViewsState);
const views = coreViews.map(convertCoreViewToView);
return views?.find((view) => view.id === viewId);
},
});
@@ -1,4 +1,5 @@
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { coreViewsState } from '@/views/states/coreViewState';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { selectorFamily } from 'recoil';
export const prefetchViewIdsFromObjectMetadataItemFamilySelector =
@@ -7,7 +8,9 @@ export const prefetchViewIdsFromObjectMetadataItemFamilySelector =
get:
({ objectMetadataItemId }) =>
({ get }) => {
const views = get(prefetchViewsState);
const coreViews = get(coreViewsState);
const views = coreViews.map(convertCoreViewToView);
return views
.filter((view) => view.objectMetadataId === objectMetadataItemId)
.map((view) => view.id);
@@ -1,10 +1,13 @@
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { coreViewsState } from '@/views/states/coreViewState';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { selector } from 'recoil';
export const prefetchViewLengthSelector = selector<number>({
key: 'prefetchViewLengthSelector',
get: ({ get }) => {
const views = get(prefetchViewsState);
const coreViews = get(coreViewsState);
const views = coreViews.map(convertCoreViewToView);
return views?.length ?? 0;
},
});
@@ -1,5 +1,6 @@
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { coreViewsState } from '@/views/states/coreViewState';
import { type View } from '@/views/types/View';
import { convertCoreViewToView } from '@/views/utils/convertCoreViewToView';
import { selectorFamily } from 'recoil';
export const prefetchViewsFromObjectMetadataItemFamilySelector = selectorFamily<
@@ -10,9 +11,14 @@ export const prefetchViewsFromObjectMetadataItemFamilySelector = selectorFamily<
get:
({ objectMetadataItemId }) =>
({ get }) => {
const views = get(prefetchViewsState);
return views
.filter((view) => view.objectMetadataId === objectMetadataItemId)
.sort((a, b) => a.position - b.position);
const coreViews = get(coreViewsState);
const views = coreViews.map(convertCoreViewToView);
const filteredViews = views.filter(
(view) => view.objectMetadataId === objectMetadataItemId,
);
return filteredViews.sort((a, b) => a.position - b.position);
},
});
@@ -19,6 +19,8 @@ import { getDateFormatFromWorkspaceDateFormat } from '@/localization/utils/getDa
import { getTimeFormatFromWorkspaceTimeFormat } from '@/localization/utils/getTimeFormatFromWorkspaceTimeFormat';
import { AppPath } from '@/types/AppPath';
import { getDateFnsLocale } from '@/ui/field/display/utils/getDateFnsLocale.util';
import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { type ColorScheme } from '@/workspace-member/types/WorkspaceMember';
import { enUS } from 'date-fns/locale';
import { useEffect } from 'react';
@@ -32,6 +34,7 @@ import {
} from '~/generated-metadata/graphql';
import { dateLocaleState } from '~/localization/states/dateLocaleState';
import { dynamicActivate } from '~/utils/i18n/dynamicActivate';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { isMatchingLocation } from '~/utils/isMatchingLocation';
export const UserProviderEffect = () => {
@@ -63,6 +66,20 @@ export const UserProviderEffect = () => {
[],
);
const setCoreViews = useRecoilCallback(
({ set, snapshot }) =>
(coreViews: CoreViewWithRelations[]) => {
const existingCoreViews = snapshot
.getLoadable(coreViewsState)
.getValue();
if (!isDeeplyEqual(existingCoreViews, coreViews)) {
set(coreViewsState, coreViews);
}
},
[],
);
const setCurrentWorkspaceMember = useSetRecoilState(
currentWorkspaceMemberState,
);
@@ -110,6 +127,10 @@ export const UserProviderEffect = () => {
});
}
if (isDefined(queryData.currentUser?.currentWorkspace?.views)) {
setCoreViews(queryData.currentUser.currentWorkspace.views);
}
const {
workspaceMember,
workspaceMembers,
@@ -181,7 +202,8 @@ export const UserProviderEffect = () => {
setDateTimeFormat,
setCurrentWorkspaceMembersWithDeleted,
updateLocaleCatalog,
setCoreViews,
]);
return <></>;
return null;
};
@@ -5,12 +5,7 @@ import {
import { OBJECT_PERMISSION_FRAGMENT } from '@/settings/roles/graphql/fragments/objectPermissionFragment';
import { ROLE_FRAGMENT } from '@/settings/roles/graphql/fragments/roleFragment';
import { WORKSPACE_URLS_FRAGMENT } from '@/users/graphql/fragments/workspaceUrlsFragment';
import { VIEW_FIELD_FRAGMENT } from '@/views/graphql/fragments/viewFieldFragment';
import { VIEW_FILTER_FRAGMENT } from '@/views/graphql/fragments/viewFilterFragment';
import { VIEW_FILTER_GROUP_FRAGMENT } from '@/views/graphql/fragments/viewFilterGroupFragment';
import { VIEW_FRAGMENT } from '@/views/graphql/fragments/viewFragment';
import { VIEW_GROUP_FRAGMENT } from '@/views/graphql/fragments/viewGroupFragment';
import { VIEW_SORT_FRAGMENT } from '@/views/graphql/fragments/viewSortFragment';
import { DELETED_WORKSPACE_MEMBER_QUERY_FRAGMENT } from '@/workspace-member/graphql/fragments/deletedWorkspaceMemberQueryFragment';
import { WORKSPACE_MEMBER_QUERY_FRAGMENT } from '@/workspace-member/graphql/fragments/workspaceMemberQueryFragment';
import { gql } from '@apollo/client';
@@ -104,21 +99,6 @@ export const USER_QUERY_FRAGMENT = gql`
isTwoFactorAuthenticationEnforced
views {
...ViewFragment
viewFields {
...ViewFieldFragment
}
viewFilters {
...ViewFilterFragment
}
viewFilterGroups {
...ViewFilterGroupFragment
}
viewSorts {
...ViewSortFragment
}
viewGroups {
...ViewGroupFragment
}
}
}
availableWorkspaces {
@@ -133,11 +113,6 @@ export const USER_QUERY_FRAGMENT = gql`
${WORKSPACE_URLS_FRAGMENT}
${ROLE_FRAGMENT}
${VIEW_FRAGMENT}
${VIEW_FIELD_FRAGMENT}
${VIEW_FILTER_FRAGMENT}
${VIEW_FILTER_GROUP_FRAGMENT}
${VIEW_SORT_FRAGMENT}
${VIEW_GROUP_FRAGMENT}
${AVAILABLE_WORKSPACES_FOR_AUTH_FRAGMENT}
${AVAILABLE_WORKSPACE_FOR_AUTH_FRAGMENT}
`;
@@ -13,14 +13,11 @@ import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { useSetRecoilComponentState } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentState';
import { ViewBarFilterDropdown } from '@/views/components/ViewBarFilterDropdown';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { MAIN_CONTEXT_STORE_INSTANCE_ID } from '@/context-store/constants/MainContextStoreInstanceId';
import { RecordComponentInstanceContextsWrapper } from '@/object-record/components/RecordComponentInstanceContextsWrapper';
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
import { VIEW_BAR_FILTER_DROPDOWN_ID } from '@/views/constants/ViewBarFilterDropdownId';
import { type View } from '@/views/types/View';
import { coreViewsState } from '@/views/states/coreViewState';
import { within } from '@storybook/test';
import { useSetRecoilState } from 'recoil';
import {
@@ -32,6 +29,10 @@ import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import {
mockedCoreViewsData,
mockedViewsData,
} from '~/testing/mock-data/views';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
const meta: Meta<typeof ViewBarFilterDropdown> = {
@@ -50,36 +51,20 @@ const meta: Meta<typeof ViewBarFilterDropdown> = {
);
const setPrefetchViews = useSetRecoilState(prefetchViewsState);
const setCoreViews = useSetRecoilState(coreViewsState);
const mockView: View = {
id: 'view-1',
name: 'Test View',
objectMetadataId: companyObjectMetadataItem.id,
viewFilters: [],
viewFilterGroups: [],
type: ViewType.Table,
key: null,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFields: [],
viewGroups: [],
viewSorts: [],
kanbanFieldMetadataId: '',
kanbanAggregateOperation: AggregateOperations.COUNT,
icon: '',
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
__typename: 'View',
};
const mockView = mockedViewsData[0];
const mockCoreView = mockedCoreViewsData[0];
setPrefetchViews([mockView]);
setCoreViews([mockCoreView]);
const setCurrentViewId = useSetRecoilComponentState(
contextStoreCurrentViewIdComponentState,
MAIN_CONTEXT_STORE_INSTANCE_ID,
);
setCurrentViewId('view-1');
setCurrentViewId(mockView.id);
const columns = companyObjectMetadataItem.fields.map(
(fieldMetadataItem, index) =>
@@ -1,6 +1,17 @@
import { VIEW_FIELD_FRAGMENT } from '@/views/graphql/fragments/viewFieldFragment';
import { VIEW_FILTER_FRAGMENT } from '@/views/graphql/fragments/viewFilterFragment';
import { VIEW_FILTER_GROUP_FRAGMENT } from '@/views/graphql/fragments/viewFilterGroupFragment';
import { VIEW_GROUP_FRAGMENT } from '@/views/graphql/fragments/viewGroupFragment';
import { VIEW_SORT_FRAGMENT } from '@/views/graphql/fragments/viewSortFragment';
import { gql } from '@apollo/client';
export const VIEW_FRAGMENT = gql`
${VIEW_FIELD_FRAGMENT}
${VIEW_FILTER_FRAGMENT}
${VIEW_FILTER_GROUP_FRAGMENT}
${VIEW_SORT_FRAGMENT}
${VIEW_GROUP_FRAGMENT}
fragment ViewFragment on CoreView {
id
name
@@ -16,5 +27,20 @@ export const VIEW_FRAGMENT = gql`
createdAt
updatedAt
anyFieldFilterValue
viewFields {
...ViewFieldFragment
}
viewFilters {
...ViewFilterFragment
}
viewFilterGroups {
...ViewFilterGroupFragment
}
viewSorts {
...ViewSortFragment
}
viewGroups {
...ViewGroupFragment
}
}
`;
@@ -3,19 +3,23 @@ import { renderHook } from '@testing-library/react';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups } from '@/views/hooks/useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups';
import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { type View } from '@/views/types/View';
import { type ViewFilterGroup } from '@/views/types/ViewFilterGroup';
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator } from '@/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator';
import { act } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { type CoreViewFilterGroup } from '~/generated/graphql';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import {
mockedCoreViewsData,
mockedViewsData,
} from '~/testing/mock-data/views';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
const mockObjectMetadataItemNameSingular = 'company';
@@ -40,27 +44,29 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
positionInViewFilterGroup: 0,
};
const mockView: View = {
id: 'view-1',
name: 'Test View',
objectMetadataId: mockObjectMetadataItem.id,
viewFilters: [],
viewFilterGroups: [mockViewFilterGroup],
type: ViewType.Table,
key: null,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFields: [],
viewGroups: [],
viewSorts: [],
kanbanFieldMetadataId: '',
kanbanAggregateOperation: AggregateOperations.COUNT,
icon: '',
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
__typename: 'View',
const allCompaniesView = mockedViewsData[0];
const allCompaniesCoreView = mockedCoreViewsData[0];
const mockCoreViewFilterGroup: Omit<CoreViewFilterGroup, 'workspaceId'> = {
__typename: 'CoreViewFilterGroup',
id: 'filter-group-1',
viewId: allCompaniesCoreView.id,
logicalOperator: ViewFilterGroupLogicalOperator.AND,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
positionInViewFilterGroup: 0,
};
const mockView = {
...allCompaniesView,
viewFilterGroups: [mockViewFilterGroup],
} satisfies View;
const mockCoreView = {
...allCompaniesCoreView,
viewFilterGroups: [mockCoreViewFilterGroup],
} satisfies CoreViewWithRelations;
it('should apply view filter groups from current view', () => {
const { result } = renderHook(
() => {
@@ -85,6 +91,7 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
mockObjectMetadataItemNameSingular,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(prefetchViewsState, [mockView]);
snapshot.set(coreViewsState, [mockCoreView]);
},
}),
},
@@ -142,6 +149,7 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
);
snapshot.set(prefetchViewsState, []);
snapshot.set(coreViewsState, []);
},
}),
},
@@ -186,6 +194,9 @@ describe('useApplyCurrentViewFilterGroupsToCurrentRecordFilterGroups', () => {
snapshot.set(prefetchViewsState, [
{ ...mockView, viewFilterGroups: [] },
]);
snapshot.set(coreViewsState, [
{ ...mockCoreView, viewFilterGroups: [] },
]);
},
}),
},
@@ -4,17 +4,24 @@ import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { type View } from '@/views/types/View';
import { type ViewFilter } from '@/views/types/ViewFilter';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import { act } from 'react';
import { ViewFilterOperand } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import {
type CoreViewFilter,
ViewFilterOperand as CoreViewFilterOperand,
} from '~/generated/graphql';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import {
mockedCoreViewsData,
mockedViewsData,
} from '~/testing/mock-data/views';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { useApplyCurrentViewFiltersToCurrentRecordFilters } from '../useApplyCurrentViewFiltersToCurrentRecordFilters';
@@ -31,6 +38,9 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
);
}
const allCompaniesView = mockedViewsData[0];
const allCompaniesCoreView = mockedCoreViewsData[0];
const mockFieldMetadataItem = mockObjectMetadataItem.fields[0];
const mockViewFilter: ViewFilter = {
@@ -39,31 +49,46 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
fieldMetadataId: mockFieldMetadataItem.id,
operand: ViewFilterOperand.Contains,
value: 'test',
displayValue: mockFieldMetadataItem.label,
displayValue: 'test',
viewFilterGroupId: 'group-1',
positionInViewFilterGroup: 0,
};
const mockView: View = {
id: 'view-1',
name: 'Test View',
objectMetadataId: mockObjectMetadataItem.id,
viewFilters: [mockViewFilter],
type: ViewType.Table,
key: null,
isCompact: false,
openRecordIn: ViewOpenRecordInType.SIDE_PANEL,
viewFields: [],
viewGroups: [],
viewSorts: [],
kanbanFieldMetadataId: '',
kanbanAggregateOperation: AggregateOperations.COUNT,
icon: '',
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
__typename: 'View',
const mockCoreViewFilter: Omit<CoreViewFilter, 'workspaceId'> = {
__typename: 'CoreViewFilter',
id: 'filter-1',
fieldMetadataId: mockFieldMetadataItem.id,
operand: CoreViewFilterOperand.CONTAINS,
value: 'test',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
viewId: allCompaniesCoreView.id,
positionInViewFilterGroup: 0,
viewFilterGroupId: 'group-1',
};
const mockView = {
...allCompaniesView,
viewFilters: [mockViewFilter],
} satisfies View;
const mockCoreView = {
...allCompaniesCoreView,
viewFilters: [mockCoreViewFilter],
} satisfies CoreViewWithRelations;
const wrapper = getJestMetadataAndApolloMocksAndActionMenuWrapper({
apolloMocks: [],
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
contextStoreCurrentViewId: mockView.id,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(prefetchViewsState, [mockView]);
snapshot.set(coreViewsState, [mockCoreView]);
},
});
it('should apply filters from current view', () => {
const { result } = renderHook(
() => {
@@ -80,16 +105,7 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
};
},
{
wrapper: getJestMetadataAndApolloMocksAndActionMenuWrapper({
apolloMocks: [],
componentInstanceId: 'instanceId',
contextStoreCurrentObjectMetadataNameSingular:
mockObjectMetadataItemNameSingular,
contextStoreCurrentViewId: mockView.id,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(prefetchViewsState, [mockView]);
},
}),
wrapper,
},
);
@@ -108,6 +124,7 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
positionInRecordFilterGroup: mockViewFilter.positionInViewFilterGroup,
label: mockFieldMetadataItem.label,
type: getFilterTypeFromFieldType(mockFieldMetadataItem.type),
subFieldName: null,
} satisfies RecordFilter,
]);
});
@@ -141,6 +158,7 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
mockView.id,
);
snapshot.set(prefetchViewsState, []);
snapshot.set(coreViewsState, []);
},
}),
},
@@ -184,6 +202,9 @@ describe('useApplyCurrentViewFiltersToCurrentRecordFilters', () => {
snapshot.set(prefetchViewsState, [
{ ...mockView, viewFilters: [] },
]);
snapshot.set(coreViewsState, [
{ ...mockCoreView, viewFilters: [] },
]);
},
}),
},
@@ -10,10 +10,16 @@ import { type ViewSort } from '@/views/types/ViewSort';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
import { prefetchViewsState } from '@/prefetch/states/prefetchViewsState';
import { coreViewsState } from '@/views/states/coreViewState';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { type View } from '@/views/types/View';
import { isDefined } from 'twenty-shared/utils';
import { ViewSortDirection, type CoreViewSort } from '~/generated/graphql';
import { getJestMetadataAndApolloMocksAndActionMenuWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksAndActionMenuWrapper';
import { mockedViewsData } from '~/testing/mock-data/views';
import {
mockedCoreViewsData,
mockedViewsData,
} from '~/testing/mock-data/views';
import { generatedMockObjectMetadataItems } from '~/testing/utils/generatedMockObjectMetadataItems';
import { useApplyCurrentViewSortsToCurrentRecordSorts } from '../useApplyCurrentViewSortsToCurrentRecordSorts';
@@ -46,12 +52,28 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
};
const allCompaniesView = mockedViewsData[0];
const allCompaniesCoreView = mockedCoreViewsData[0];
const mockCoreViewSort: Omit<CoreViewSort, 'workspaceId'> = {
__typename: 'CoreViewSort',
id: 'sort-1',
fieldMetadataId: mockFieldMetadataItem.id,
direction: ViewSortDirection.ASC,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
viewId: allCompaniesCoreView.id,
};
const mockView = {
...allCompaniesView,
viewSorts: [mockViewSort],
} satisfies View;
const mockCoreView = {
...allCompaniesCoreView,
viewSorts: [mockCoreViewSort],
} satisfies CoreViewWithRelations;
it('should apply sorts from current view', () => {
const { result } = renderHook(
() => {
@@ -76,6 +98,7 @@ describe('useApplyCurrentViewSortsToCurrentRecordSorts', () => {
contextStoreCurrentViewId: mockView.id,
onInitializeRecoilSnapshot: (snapshot) => {
snapshot.set(prefetchViewsState, [mockView]);
snapshot.set(coreViewsState, [mockCoreView]);
},
}),
},
@@ -16,6 +16,7 @@ import { usePersistViewFilterGroupRecords } from '@/views/hooks/internal/usePers
import { usePersistViewFilterRecords } from '@/views/hooks/internal/usePersistViewFilterRecords';
import { usePersistViewGroupRecords } from '@/views/hooks/internal/usePersistViewGroupRecords';
import { usePersistViewSortRecords } from '@/views/hooks/internal/usePersistViewSortRecords';
import { coreViewsState } from '@/views/states/coreViewState';
import { isPersistingViewFieldsState } from '@/views/states/isPersistingViewFieldsState';
import { type GraphQLView } from '@/views/types/GraphQLView';
import { type View } from '@/views/types/View';
@@ -32,7 +33,12 @@ import { useFeatureFlagsMap } from '@/workspace/hooks/useFeatureFlagsMap';
import { useRecoilCallback } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import { FeatureFlagKey, useCreateCoreViewMutation } from '~/generated/graphql';
import {
FeatureFlagKey,
useCreateCoreViewMutation,
useFindManyCoreViewsLazyQuery,
} from '~/generated/graphql';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
@@ -64,6 +70,8 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const [findManyCoreViewsLazy] = useFindManyCoreViewsLazyQuery();
const { findManyRecordsLazy } = useLazyFindManyRecords({
objectNameSingular: CoreObjectNameSingular.View,
fetchPolicy: 'network-only',
@@ -249,7 +257,28 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
await createViewSortRecords(viewSortsToCreate, { id: newViewId });
}
await findManyRecordsLazy();
if (isCoreViewEnabled) {
const result = await findManyCoreViewsLazy({
variables: {
objectMetadataId: objectMetadataItem.id,
},
fetchPolicy: 'network-only',
});
const existingCoreViews = snapshot
.getLoadable(coreViewsState)
.getValue();
if (
isDefined(result.data?.getCoreViews) &&
!isDeeplyEqual(existingCoreViews, result.data.getCoreViews)
) {
set(coreViewsState, result.data.getCoreViews);
}
} else {
await findManyRecordsLazy();
}
set(isPersistingViewFieldsState, false);
return newViewId;
},
@@ -269,6 +298,8 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
currentRecordFilterGroups,
isCoreViewEnabled,
createCoreViewMutation,
findManyCoreViewsLazy,
objectMetadataItem.id,
],
);
@@ -1,4 +1,5 @@
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { type CoreViewFilter } from '~/generated/graphql';
import { type ViewFilter } from '../types/ViewFilter';
import { getFilterableFieldsWithVectorSearch } from '../utils/getFilterableFieldsWithVectorSearch';
import { mapViewFiltersToFilters } from '../utils/mapViewFiltersToFilters';
@@ -6,7 +7,9 @@ import { mapViewFiltersToFilters } from '../utils/mapViewFiltersToFilters';
export const useMapViewFiltersToFilters = () => {
const { objectMetadataItem } = useRecordIndexContextOrThrow();
const mapViewFiltersToRecordFilters = (viewFilters: ViewFilter[]) => {
const mapViewFiltersToRecordFilters = (
viewFilters: ViewFilter[] | CoreViewFilter[],
) => {
const filterableFieldMetadataItems =
getFilterableFieldsWithVectorSearch(objectMetadataItem);
return mapViewFiltersToFilters(viewFilters, filterableFieldMetadataItems);
@@ -0,0 +1,7 @@
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { createState } from 'twenty-ui/utilities';
export const coreViewsState = createState<CoreViewWithRelations[]>({
key: 'coreViewsState',
defaultValue: [],
});
@@ -4,11 +4,15 @@ import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataIte
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
import { isSystemSearchVectorField } from '@/object-record/utils/isSystemSearchVectorField';
import { type CompositeFieldSubFieldName } from '@/settings/data-model/types/CompositeFieldSubFieldName';
import { convertViewFilterOperandFromCore } from '@/views/utils/convertViewFilterOperandFromCore';
import { type ViewFilterOperand } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type CoreViewFilter } from '~/generated/graphql';
import { type ViewFilter } from '../types/ViewFilter';
export const mapViewFiltersToFilters = (
viewFilters: ViewFilter[],
viewFilters: ViewFilter[] | CoreViewFilter[],
availableFieldMetadataItems: FieldMetadataItem[],
): RecordFilter[] => {
return viewFilters
@@ -31,17 +35,25 @@ export const mapViewFiltersToFilters = (
? 'Search'
: availableFieldMetadataItem.label;
const operand =
viewFilter.__typename === 'CoreViewFilter'
? convertViewFilterOperandFromCore(viewFilter.operand)
: (viewFilter.operand as ViewFilterOperand);
return {
id: viewFilter.id,
fieldMetadataId: viewFilter.fieldMetadataId,
value: viewFilter.value,
displayValue: viewFilter.displayValue,
operand: viewFilter.operand,
displayValue:
'displayValue' in viewFilter
? viewFilter.displayValue
: viewFilter.value,
operand,
recordFilterGroupId: viewFilter.viewFilterGroupId,
positionInRecordFilterGroup: viewFilter.positionInViewFilterGroup,
label,
type: filterType,
subFieldName: viewFilter.subFieldName,
subFieldName: viewFilter.subFieldName as CompositeFieldSubFieldName,
} satisfies RecordFilter;
})
.filter(isDefined);
@@ -11,7 +11,7 @@ import { viewPickerModeComponentState } from '@/views/view-picker/states/viewPic
import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState';
import { viewPickerTypeComponentState } from '@/views/view-picker/states/viewPickerTypeComponentState';
import { useRecoilCallback } from 'recoil';
import { v4 } from 'uuid';
import { isDefined } from 'twenty-shared/utils';
export const useCreateViewFromCurrentState = () => {
const { closeAndResetViewPicker } = useCloseAndResetViewPicker();
@@ -73,14 +73,11 @@ export const useCreateViewFromCurrentState = () => {
const shouldCopyFiltersAndSortsAndAggregate =
viewPickerMode === 'create-from-current';
const id = v4();
set(viewPickerIsPersistingCallbackState, true);
set(viewPickerIsDirtyCallbackState, false);
await createViewFromCurrentView(
const createdViewId = await createViewFromCurrentView(
{
id,
name,
icon: iconKey,
type,
@@ -89,8 +86,10 @@ export const useCreateViewFromCurrentState = () => {
shouldCopyFiltersAndSortsAndAggregate,
);
closeAndResetViewPicker();
changeView(id);
if (isDefined(createdViewId)) {
closeAndResetViewPicker();
changeView(createdViewId);
}
},
[
closeAndResetViewPicker,
@@ -1,8 +1,14 @@
import { AggregateOperations } from '@/object-record/record-table/constants/AggregateOperations';
import { type CoreViewWithRelations } from '@/views/types/CoreViewWithRelations';
import { type View } from '@/views/types/View';
import { ViewKey } from '@/views/types/ViewKey';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import { ViewType } from '@/views/types/ViewType';
import {
ViewKey as CoreViewKey,
ViewOpenRecordIn as CoreViewOpenRecordIn,
ViewType as CoreViewType,
} from '~/generated-metadata/graphql';
import { getMockObjectMetadataItemOrThrow } from '~/testing/utils/getMockObjectMetadataItemOrThrow';
const companyObjectMetadata = getMockObjectMetadataItemOrThrow('company');
@@ -94,3 +100,82 @@ export const mockedViewsData: View[] = [
__typename: 'View',
},
];
export const mockedCoreViewsData: CoreViewWithRelations[] = [
{
id: '37a8a866-eb17-4e76-9382-03143a2f6a80',
name: 'All companies',
objectMetadataId: companyObjectMetadata.id,
type: CoreViewType.TABLE,
icon: 'IconSkyline',
key: CoreViewKey.INDEX,
kanbanAggregateOperation: AggregateOperations.COUNT,
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: CoreViewOpenRecordIn.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],
viewFilters: [],
viewSorts: [],
__typename: 'CoreView',
},
{
id: '6095799e-b48f-4e00-b071-10818083593a',
name: 'All people',
objectMetadataId: personObjectMetadata.id,
type: CoreViewType.TABLE,
icon: 'IconPerson',
key: CoreViewKey.INDEX,
kanbanAggregateOperation: AggregateOperations.COUNT,
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: CoreViewOpenRecordIn.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],
viewFilters: [],
viewSorts: [],
__typename: 'CoreView',
},
{
id: 'e26f66b7-f890-4a5c-b4d2-ec09987b5308',
name: 'All opportunities',
objectMetadataId: opportunityObjectMetadata.id,
type: CoreViewType.KANBAN,
icon: 'IconOpportunity',
key: CoreViewKey.INDEX,
kanbanAggregateOperation: AggregateOperations.COUNT,
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: CoreViewOpenRecordIn.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],
viewFilters: [],
viewSorts: [],
__typename: 'CoreView',
},
{
id: '5c307222-1dd5-4ff3-ab06-8d990e9b3c74',
name: 'All companies (v2)',
objectMetadataId: companyObjectMetadata.id,
type: CoreViewType.TABLE,
icon: 'IconSkyline',
key: null,
kanbanAggregateOperation: AggregateOperations.COUNT,
kanbanAggregateOperationFieldMetadataId: '',
position: 0,
isCompact: false,
openRecordIn: CoreViewOpenRecordIn.SIDE_PANEL,
viewFilterGroups: [],
viewGroups: [],
viewFields: [],
viewFilters: [],
viewSorts: [],
__typename: 'CoreView',
},
];
+1
View File
@@ -48,6 +48,7 @@
"dist",
"assets",
"accessibility",
"assets",
"components",
"display",
"feedback",