mirror of
https://github.com/twentyhq/twenty.git
synced 2025-01-04 18:21:59 +03:00
feat: create default opportunities view on workspace creation + add seed data (#1461)
Closes #1314
This commit is contained in:
parent
08b56ec7e2
commit
5c7660f588
@ -2495,7 +2495,7 @@ export type ViewField = {
|
||||
key: Scalars['String'];
|
||||
name: Scalars['String'];
|
||||
objectId: Scalars['String'];
|
||||
size: Scalars['Int'];
|
||||
size?: Maybe<Scalars['Int']>;
|
||||
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<Scalars['Int']>;
|
||||
view: ViewCreateNestedOneWithoutFieldsInput;
|
||||
};
|
||||
|
||||
@ -2516,7 +2516,7 @@ export type ViewFieldCreateManyInput = {
|
||||
key: Scalars['String'];
|
||||
name: Scalars['String'];
|
||||
objectId: Scalars['String'];
|
||||
size: Scalars['Int'];
|
||||
size?: InputMaybe<Scalars['Int']>;
|
||||
viewId: Scalars['String'];
|
||||
};
|
||||
|
||||
@ -2592,7 +2592,7 @@ export type ViewFieldWhereInput = {
|
||||
key?: InputMaybe<StringFilter>;
|
||||
name?: InputMaybe<StringFilter>;
|
||||
objectId?: InputMaybe<StringFilter>;
|
||||
size?: InputMaybe<IntFilter>;
|
||||
size?: InputMaybe<IntNullableFilter>;
|
||||
view?: InputMaybe<ViewRelationFilter>;
|
||||
viewId?: InputMaybe<StringFilter>;
|
||||
};
|
||||
@ -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<ViewFilterWhereInput>;
|
||||
|
@ -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<ViewFieldMetadata>,
|
||||
@ -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<ViewFieldMetadata>
|
||||
>((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<ColumnDefinition<ViewFieldMetadata> | 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<ColumnDefinition<ViewFieldMetadata>>(assertNotNull);
|
||||
|
||||
if (!isDeeplyEqual(tableColumns, nextColumns)) {
|
||||
setSavedTableColumns(nextColumns);
|
||||
|
@ -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 = <Entity, SortField>({
|
||||
const { handleViewsChange, isFetchingViews } = useViews({
|
||||
objectId,
|
||||
onViewCreate: handleViewCreate,
|
||||
type: ViewType.Table,
|
||||
});
|
||||
const { createViewFields, persistColumns } = useTableViewFields({
|
||||
objectId,
|
||||
|
@ -24,9 +24,11 @@ import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
export const useViews = ({
|
||||
objectId,
|
||||
onViewCreate,
|
||||
type,
|
||||
}: {
|
||||
objectId: 'company' | 'person';
|
||||
onViewCreate: (viewId: string) => Promise<void>;
|
||||
type: ViewType;
|
||||
}) => {
|
||||
const [currentTableViewId, setCurrentTableViewId] = useRecoilScopedState(
|
||||
currentTableViewIdState,
|
||||
@ -86,6 +88,7 @@ export const useViews = ({
|
||||
variables: {
|
||||
where: {
|
||||
objectId: { equals: objectId },
|
||||
type: { equals: type },
|
||||
},
|
||||
},
|
||||
onCompleted: (data) => {
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "viewFields" ALTER COLUMN "size" DROP NOT NULL;
|
@ -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
|
||||
|
@ -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,
|
||||
},
|
||||
}),
|
||||
),
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user