diff --git a/front/src/generated/graphql.tsx b/front/src/generated/graphql.tsx index b32e7edc3..fbfdfb967 100644 --- a/front/src/generated/graphql.tsx +++ b/front/src/generated/graphql.tsx @@ -2495,7 +2495,7 @@ export type ViewField = { key: Scalars['String']; name: Scalars['String']; objectId: Scalars['String']; - size: Scalars['Int']; + size?: Maybe; view: View; viewId: Scalars['String']; }; @@ -2506,7 +2506,7 @@ export type ViewFieldCreateInput = { key: Scalars['String']; name: Scalars['String']; objectId: Scalars['String']; - size: Scalars['Int']; + size?: InputMaybe; view: ViewCreateNestedOneWithoutFieldsInput; }; @@ -2516,7 +2516,7 @@ export type ViewFieldCreateManyInput = { key: Scalars['String']; name: Scalars['String']; objectId: Scalars['String']; - size: Scalars['Int']; + size?: InputMaybe; viewId: Scalars['String']; }; @@ -2592,7 +2592,7 @@ export type ViewFieldWhereInput = { key?: InputMaybe; name?: InputMaybe; objectId?: InputMaybe; - size?: InputMaybe; + size?: InputMaybe; view?: InputMaybe; viewId?: InputMaybe; }; @@ -3520,7 +3520,7 @@ export type UpdateViewFieldMutationVariables = Exact<{ }>; -export type UpdateViewFieldMutation = { __typename?: 'Mutation', updateOneViewField: { __typename?: 'ViewField', index: number, isVisible: boolean, key: string, name: string, size: number } }; +export type UpdateViewFieldMutation = { __typename?: 'Mutation', updateOneViewField: { __typename?: 'ViewField', index: number, isVisible: boolean, key: string, name: string, size?: number | null } }; export type UpdateViewFilterMutationVariables = Exact<{ data: ViewFilterUpdateInput; @@ -3544,7 +3544,7 @@ export type GetViewFieldsQueryVariables = Exact<{ }>; -export type GetViewFieldsQuery = { __typename?: 'Query', viewFields: Array<{ __typename?: 'ViewField', index: number, isVisible: boolean, key: string, name: string, size: number }> }; +export type GetViewFieldsQuery = { __typename?: 'Query', viewFields: Array<{ __typename?: 'ViewField', index: number, isVisible: boolean, key: string, name: string, size?: number | null }> }; export type GetViewFiltersQueryVariables = Exact<{ where?: InputMaybe; diff --git a/front/src/modules/views/hooks/useTableViewFields.ts b/front/src/modules/views/hooks/useTableViewFields.ts index 1383a6920..ae836eb42 100644 --- a/front/src/modules/views/hooks/useTableViewFields.ts +++ b/front/src/modules/views/hooks/useTableViewFields.ts @@ -1,10 +1,7 @@ import { useCallback } from 'react'; import { useRecoilValue, useSetRecoilState } from 'recoil'; -import type { - ViewFieldMetadata, - ViewFieldTextMetadata, -} from '@/ui/editable-field/types/ViewField'; +import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField'; import { availableTableColumnsScopedState } from '@/ui/table/states/availableTableColumnsScopedState'; import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext'; import { savedTableColumnsScopedState } from '@/ui/table/states/savedTableColumnsScopedState'; @@ -20,14 +17,9 @@ import { useGetViewFieldsQuery, useUpdateViewFieldMutation, } from '~/generated/graphql'; +import { assertNotNull } from '~/utils/assert'; import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; -const DEFAULT_VIEW_FIELD_METADATA: ViewFieldTextMetadata = { - type: 'text', - placeHolder: '', - fieldName: '', -}; - const toViewFieldInput = ( objectId: 'company' | 'person', fieldDefinition: ColumnDefinition, @@ -119,7 +111,6 @@ export const useTableViewFields = ({ variables: { orderBy: { index: SortOrder.Asc }, where: { - objectId: { equals: objectId }, viewId: { equals: currentTableViewId }, }, }, @@ -130,18 +121,24 @@ export const useTableViewFields = ({ return refetch(); } - const nextColumns = data.viewFields.map< - ColumnDefinition - >((viewField) => ({ - ...(columnDefinitions.find(({ key }) => viewField.key === key) || { - metadata: DEFAULT_VIEW_FIELD_METADATA, - }), - key: viewField.key, - name: viewField.name, - index: viewField.index, - size: viewField.size, - isVisible: viewField.isVisible, - })); + const nextColumns = data.viewFields + .map | null>((viewField) => { + const columnDefinition = columnDefinitions.find( + ({ key }) => viewField.key === key, + ); + + return columnDefinition + ? { + ...columnDefinition, + key: viewField.key, + name: viewField.name, + index: viewField.index, + size: viewField.size ?? columnDefinition.size, + isVisible: viewField.isVisible, + } + : null; + }) + .filter>(assertNotNull); if (!isDeeplyEqual(tableColumns, nextColumns)) { setSavedTableColumns(nextColumns); diff --git a/front/src/modules/views/hooks/useTableViews.ts b/front/src/modules/views/hooks/useTableViews.ts index dbd981689..5b03f0ed4 100644 --- a/front/src/modules/views/hooks/useTableViews.ts +++ b/front/src/modules/views/hooks/useTableViews.ts @@ -10,6 +10,7 @@ import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedSta import { currentTableViewIdState } from '@/ui/table/states/tableViewsState'; import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition'; import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue'; +import { ViewType } from '~/generated/graphql'; import { useTableViewFields } from './useTableViewFields'; import { useViewFilters } from './useViewFilters'; @@ -44,6 +45,7 @@ export const useTableViews = ({ const { handleViewsChange, isFetchingViews } = useViews({ objectId, onViewCreate: handleViewCreate, + type: ViewType.Table, }); const { createViewFields, persistColumns } = useTableViewFields({ objectId, diff --git a/front/src/modules/views/hooks/useViews.ts b/front/src/modules/views/hooks/useViews.ts index 564373b07..3d20b1b4a 100644 --- a/front/src/modules/views/hooks/useViews.ts +++ b/front/src/modules/views/hooks/useViews.ts @@ -24,9 +24,11 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual'; export const useViews = ({ objectId, onViewCreate, + type, }: { objectId: 'company' | 'person'; onViewCreate: (viewId: string) => Promise; + type: ViewType; }) => { const [currentTableViewId, setCurrentTableViewId] = useRecoilScopedState( currentTableViewIdState, @@ -86,6 +88,7 @@ export const useViews = ({ variables: { where: { objectId: { equals: objectId }, + type: { equals: type }, }, }, onCompleted: (data) => { diff --git a/server/src/core/view/seed-data/views.json b/server/src/core/view/seed-data/views.json index 38d407830..3c0478d00 100644 --- a/server/src/core/view/seed-data/views.json +++ b/server/src/core/view/seed-data/views.json @@ -97,5 +97,28 @@ "size": 150 } ] + }, + { + "name": "All Opportunities", + "objectId": "company", + "type": "Pipeline", + "fields": [ + { + "key": "closeDate", + "name": "Close Date" + }, + { + "key": "amount", + "name": "Amount" + }, + { + "key": "probability", + "name": "Probability" + }, + { + "key": "pointOfContact", + "name": "Point of Contact" + } + ] } ] diff --git a/server/src/database/migrations/20230905150352_make_view_field_size_optional/migration.sql b/server/src/database/migrations/20230905150352_make_view_field_size_optional/migration.sql new file mode 100644 index 000000000..60036a5cc --- /dev/null +++ b/server/src/database/migrations/20230905150352_make_view_field_size_optional/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "viewFields" ALTER COLUMN "size" DROP NOT NULL; diff --git a/server/src/database/schema.prisma b/server/src/database/schema.prisma index dd7d73f10..3dadfbe31 100644 --- a/server/src/database/schema.prisma +++ b/server/src/database/schema.prisma @@ -662,7 +662,7 @@ model ViewField { key String name String objectId String - size Int + size Int? view View @relation(fields: [viewId], references: [id], onDelete: Cascade) viewId String diff --git a/server/src/database/seeds/views.ts b/server/src/database/seeds/views.ts index fe33b65d8..fd4353101 100644 --- a/server/src/database/seeds/views.ts +++ b/server/src/database/seeds/views.ts @@ -4,6 +4,7 @@ export const seedViews = async (prisma: PrismaClient) => { const workspaceId = 'twenty-7ed9d212-1c25-4d02-bf25-6aeccf7ea419'; const companyViewId = 'twenty-5e924b69-a619-41bf-bd31-a9e8551fc9d1'; const personViewId = 'twenty-db9e6c85-c091-4fd6-88b1-c1830f5e90d1'; + const opportunitiesViewId = 'twenty-6abb47a2-7a91-4679-a538-59946f0c06a9'; await prisma.view.upsert({ where: { id: companyViewId }, @@ -149,4 +150,52 @@ export const seedViews = async (prisma: PrismaClient) => { }), ), ); + + await prisma.view.upsert({ + where: { id: opportunitiesViewId }, + update: {}, + create: { + id: opportunitiesViewId, + name: 'All Opportunities', + objectId: 'company', + type: 'Pipeline', + workspaceId, + }, + }); + + await Promise.all( + [ + { + key: 'closeDate', + name: 'Close Date', + }, + { + key: 'amount', + name: 'Amount', + }, + { + key: 'probability', + name: 'Probability', + }, + { + key: 'pointOfContact', + name: 'Point of Contact', + }, + ].map((viewField, index) => + prisma.viewField.upsert({ + where: { + viewId_key: { key: viewField.key, viewId: opportunitiesViewId }, + }, + update: {}, + create: { + ...viewField, + index, + isVisible: true, + objectId: 'company', + viewId: opportunitiesViewId, + workspaceId, + }, + }), + ), + ); };