refactor: index ViewField by viewId and key (#1416)

* refactor: index ViewField by viewId and key

Closes #1413

* refactor: rename ViewField properties
This commit is contained in:
Thaïs
2023-09-04 10:55:03 +02:00
committed by GitHub
parent c3c5cb4d1f
commit ae072b6ce5
35 changed files with 463 additions and 447 deletions

View File

@ -2458,34 +2458,34 @@ export type ViewCreateNestedOneWithoutFieldsInput = {
export type ViewField = {
__typename?: 'ViewField';
fieldName: Scalars['String'];
id: Scalars['ID'];
index: Scalars['Int'];
isVisible: Scalars['Boolean'];
objectName: Scalars['String'];
sizeInPx: Scalars['Int'];
view?: Maybe<View>;
viewId?: Maybe<Scalars['String']>;
key: Scalars['String'];
name: Scalars['String'];
objectId: Scalars['String'];
size: Scalars['Int'];
view: View;
viewId: Scalars['String'];
};
export type ViewFieldCreateInput = {
fieldName: Scalars['String'];
id?: InputMaybe<Scalars['String']>;
index: Scalars['Int'];
isVisible: Scalars['Boolean'];
objectName: Scalars['String'];
sizeInPx: Scalars['Int'];
view?: InputMaybe<ViewCreateNestedOneWithoutFieldsInput>;
key: Scalars['String'];
name: Scalars['String'];
objectId: Scalars['String'];
size: Scalars['Int'];
view: ViewCreateNestedOneWithoutFieldsInput;
};
export type ViewFieldCreateManyInput = {
fieldName: Scalars['String'];
id?: InputMaybe<Scalars['String']>;
index: Scalars['Int'];
isVisible: Scalars['Boolean'];
objectName: Scalars['String'];
sizeInPx: Scalars['Int'];
viewId?: InputMaybe<Scalars['String']>;
key: Scalars['String'];
name: Scalars['String'];
objectId: Scalars['String'];
size: Scalars['Int'];
viewId: Scalars['String'];
};
export type ViewFieldCreateNestedManyWithoutViewInput = {
@ -2503,35 +2503,35 @@ export type ViewFieldOrderByRelationAggregateInput = {
};
export type ViewFieldOrderByWithRelationInput = {
fieldName?: InputMaybe<SortOrder>;
id?: InputMaybe<SortOrder>;
index?: InputMaybe<SortOrder>;
isVisible?: InputMaybe<SortOrder>;
objectName?: InputMaybe<SortOrder>;
sizeInPx?: InputMaybe<SortOrder>;
key?: InputMaybe<SortOrder>;
name?: InputMaybe<SortOrder>;
objectId?: InputMaybe<SortOrder>;
size?: InputMaybe<SortOrder>;
view?: InputMaybe<ViewOrderByWithRelationInput>;
viewId?: InputMaybe<SortOrder>;
};
export enum ViewFieldScalarFieldEnum {
FieldName = 'fieldName',
Id = 'id',
Index = 'index',
IsVisible = 'isVisible',
ObjectName = 'objectName',
SizeInPx = 'sizeInPx',
Key = 'key',
Name = 'name',
ObjectId = 'objectId',
Size = 'size',
ViewId = 'viewId',
WorkspaceId = 'workspaceId'
}
export type ViewFieldUpdateInput = {
fieldName?: InputMaybe<Scalars['String']>;
id?: InputMaybe<Scalars['String']>;
index?: InputMaybe<Scalars['Int']>;
isVisible?: InputMaybe<Scalars['Boolean']>;
objectName?: InputMaybe<Scalars['String']>;
sizeInPx?: InputMaybe<Scalars['Int']>;
view?: InputMaybe<ViewUpdateOneWithoutFieldsNestedInput>;
key?: InputMaybe<Scalars['String']>;
name?: InputMaybe<Scalars['String']>;
objectId?: InputMaybe<Scalars['String']>;
size?: InputMaybe<Scalars['Int']>;
view?: InputMaybe<ViewUpdateOneRequiredWithoutFieldsNestedInput>;
};
export type ViewFieldUpdateManyWithoutViewNestedInput = {
@ -2546,29 +2546,27 @@ export type ViewFieldUpdateManyWithoutWorkspaceNestedInput = {
set?: InputMaybe<Array<ViewFieldWhereUniqueInput>>;
};
export type ViewFieldViewIdKeyCompoundUniqueInput = {
key: Scalars['String'];
viewId: Scalars['String'];
};
export type ViewFieldWhereInput = {
AND?: InputMaybe<Array<ViewFieldWhereInput>>;
NOT?: InputMaybe<Array<ViewFieldWhereInput>>;
OR?: InputMaybe<Array<ViewFieldWhereInput>>;
fieldName?: InputMaybe<StringFilter>;
id?: InputMaybe<StringFilter>;
index?: InputMaybe<IntFilter>;
isVisible?: InputMaybe<BoolFilter>;
objectName?: InputMaybe<StringFilter>;
sizeInPx?: InputMaybe<IntFilter>;
key?: InputMaybe<StringFilter>;
name?: InputMaybe<StringFilter>;
objectId?: InputMaybe<StringFilter>;
size?: InputMaybe<IntFilter>;
view?: InputMaybe<ViewRelationFilter>;
viewId?: InputMaybe<StringNullableFilter>;
viewId?: InputMaybe<StringFilter>;
};
export type ViewFieldWhereUniqueInput = {
id?: InputMaybe<Scalars['String']>;
workspaceId_viewId_objectName_fieldName?: InputMaybe<ViewFieldWorkspaceIdViewIdObjectNameFieldNameCompoundUniqueInput>;
};
export type ViewFieldWorkspaceIdViewIdObjectNameFieldNameCompoundUniqueInput = {
fieldName: Scalars['String'];
objectName: Scalars['String'];
viewId: Scalars['String'];
viewId_key?: InputMaybe<ViewFieldViewIdKeyCompoundUniqueInput>;
};
export type ViewFilter = {
@ -2811,6 +2809,10 @@ export type ViewUpdateManyWithoutWorkspaceNestedInput = {
set?: InputMaybe<Array<ViewWhereUniqueInput>>;
};
export type ViewUpdateOneRequiredWithoutFieldsNestedInput = {
connect?: InputMaybe<ViewWhereUniqueInput>;
};
export type ViewUpdateOneRequiredWithoutFiltersNestedInput = {
connect?: InputMaybe<ViewWhereUniqueInput>;
};
@ -2819,11 +2821,6 @@ 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>>;
@ -3477,7 +3474,7 @@ 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', index: number, isVisible: boolean, key: string, name: string, size: number } };
export type UpdateViewFilterMutationVariables = Exact<{
data: ViewFilterUpdateInput;
@ -3501,7 +3498,7 @@ 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', index: number, isVisible: boolean, key: string, name: string, size: number }> };
export type GetViewFiltersQueryVariables = Exact<{
where?: InputMaybe<ViewFilterWhereInput>;
@ -6413,11 +6410,11 @@ export type UpdateViewMutationOptions = Apollo.BaseMutationOptions<UpdateViewMut
export const UpdateViewFieldDocument = gql`
mutation UpdateViewField($data: ViewFieldUpdateInput!, $where: ViewFieldWhereUniqueInput!) {
updateOneViewField(data: $data, where: $where) {
id
fieldName
isVisible
sizeInPx
index
isVisible
key
name
size
}
}
`;
@ -6525,11 +6522,11 @@ export type UpdateViewSortMutationOptions = Apollo.BaseMutationOptions<UpdateVie
export const GetViewFieldsDocument = gql`
query GetViewFields($where: ViewFieldWhereInput, $orderBy: [ViewFieldOrderByWithRelationInput!]) {
viewFields: findManyViewField(where: $where, orderBy: $orderBy) {
id
fieldName
isVisible
sizeInPx
index
isVisible
key
name
size
}
}
`;

View File

@ -162,11 +162,11 @@ export function CompanyBoardCard() {
<EditableFieldEntityIdContext.Provider value={boardCardId}>
{viewFieldsDefinitions.map((viewField) => {
return (
<PreventSelectOnClickContainer key={viewField.id}>
<PreventSelectOnClickContainer key={viewField.key}>
<EditableFieldDefinitionContext.Provider
value={{
id: viewField.id,
label: viewField.label,
key: viewField.key,
name: viewField.name,
icon: viewField.icon,
type: viewField.metadata.type,
metadata: viewField.metadata,

View File

@ -27,11 +27,11 @@ import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadata>[] =
[
{
id: 'name',
label: 'Name',
key: 'name',
name: 'Name',
icon: <IconBuildingSkyscraper />,
size: 180,
order: 1,
index: 0,
metadata: {
type: 'chip',
urlFieldName: 'domainName',
@ -41,11 +41,11 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: true,
} as ColumnDefinition<ViewFieldChipMetadata>,
{
id: 'domainName',
label: 'URL',
key: 'domainName',
name: 'URL',
icon: <IconLink />,
size: 100,
order: 2,
index: 1,
metadata: {
type: 'url',
fieldName: 'domainName',
@ -54,11 +54,11 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: true,
} as ColumnDefinition<ViewFieldURLMetadata>,
{
id: 'accountOwner',
label: 'Account Owner',
key: 'accountOwner',
name: 'Account Owner',
icon: <IconUserCircle />,
size: 150,
order: 3,
index: 2,
metadata: {
type: 'relation',
fieldName: 'accountOwner',
@ -67,11 +67,11 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: true,
} satisfies ColumnDefinition<ViewFieldRelationMetadata>,
{
id: 'createdAt',
label: 'Creation',
key: 'createdAt',
name: 'Creation',
icon: <IconCalendarEvent />,
size: 150,
order: 4,
index: 3,
metadata: {
type: 'date',
fieldName: 'createdAt',
@ -79,11 +79,11 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: true,
} satisfies ColumnDefinition<ViewFieldDateMetadata>,
{
id: 'employees',
label: 'Employees',
key: 'employees',
name: 'Employees',
icon: <IconUsers />,
size: 150,
order: 5,
index: 4,
metadata: {
type: 'number',
fieldName: 'employees',
@ -92,11 +92,11 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: true,
} satisfies ColumnDefinition<ViewFieldNumberMetadata>,
{
id: 'linkedin',
label: 'LinkedIn',
key: 'linkedin',
name: 'LinkedIn',
icon: <IconBrandLinkedin />,
size: 170,
order: 6,
index: 5,
metadata: {
type: 'url',
fieldName: 'linkedinUrl',
@ -105,11 +105,11 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: true,
} satisfies ColumnDefinition<ViewFieldURLMetadata>,
{
id: 'address',
label: 'Address',
key: 'address',
name: 'Address',
icon: <IconMap />,
size: 170,
order: 7,
index: 6,
metadata: {
type: 'text',
fieldName: 'address',
@ -118,11 +118,11 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: true,
} satisfies ColumnDefinition<ViewFieldTextMetadata>,
{
id: 'idealCustomerProfile',
label: 'ICP',
key: 'idealCustomerProfile',
name: 'ICP',
icon: <IconTarget />,
size: 150,
order: 8,
index: 7,
metadata: {
type: 'boolean',
fieldName: 'idealCustomerProfile',
@ -130,22 +130,22 @@ export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMeta
isVisible: false,
} satisfies ColumnDefinition<ViewFieldBooleanMetadata>,
{
id: 'annualRecurringRevenue',
label: 'ARR',
key: 'annualRecurringRevenue',
name: 'ARR',
icon: <IconMoneybag />,
size: 150,
order: 8,
index: 8,
metadata: {
type: 'moneyAmount',
fieldName: 'annualRecurringRevenue',
},
} satisfies ColumnDefinition<ViewFieldMoneyMetadata>,
{
id: 'xUrl',
label: 'Twitter',
key: 'xUrl',
name: 'Twitter',
icon: <IconBrandX />,
size: 150,
order: 8,
index: 9,
metadata: {
type: 'url',
fieldName: 'xUrl',

View File

@ -25,11 +25,11 @@ import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadata>[] =
[
{
id: 'displayName',
label: 'People',
key: 'displayName',
name: 'People',
icon: <IconUser />,
size: 210,
order: 1,
index: 0,
metadata: {
type: 'double-text-chip',
firstValueFieldName: 'firstName',
@ -41,11 +41,11 @@ export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadat
},
} satisfies ColumnDefinition<ViewFieldDoubleTextChipMetadata>,
{
id: 'email',
label: 'Email',
key: 'email',
name: 'Email',
icon: <IconMail />,
size: 150,
order: 2,
index: 1,
metadata: {
type: 'email',
fieldName: 'email',
@ -53,11 +53,11 @@ export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadat
},
} satisfies ColumnDefinition<ViewFieldEmailMetadata>,
{
id: 'company',
label: 'Company',
key: 'company',
name: 'Company',
icon: <IconBuildingSkyscraper />,
size: 150,
order: 3,
index: 2,
metadata: {
type: 'relation',
fieldName: 'company',
@ -65,11 +65,11 @@ export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadat
},
} satisfies ColumnDefinition<ViewFieldRelationMetadata>,
{
id: 'phone',
label: 'Phone',
key: 'phone',
name: 'Phone',
icon: <IconPhone />,
size: 150,
order: 4,
index: 3,
metadata: {
type: 'phone',
fieldName: 'phone',
@ -77,22 +77,22 @@ export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadat
},
} satisfies ColumnDefinition<ViewFieldPhoneMetadata>,
{
id: 'createdAt',
label: 'Creation',
key: 'createdAt',
name: 'Creation',
icon: <IconCalendarEvent />,
size: 150,
order: 5,
index: 4,
metadata: {
type: 'date',
fieldName: 'createdAt',
},
} satisfies ColumnDefinition<ViewFieldDateMetadata>,
{
id: 'city',
label: 'City',
key: 'city',
name: 'City',
icon: <IconMap />,
size: 150,
order: 6,
index: 5,
metadata: {
type: 'text',
fieldName: 'city',
@ -100,11 +100,11 @@ export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadat
},
} satisfies ColumnDefinition<ViewFieldTextMetadata>,
{
id: 'jobTitle',
label: 'Job title',
key: 'jobTitle',
name: 'Job title',
icon: <IconBriefcase />,
size: 150,
order: 7,
index: 6,
metadata: {
type: 'text',
fieldName: 'jobTitle',
@ -112,11 +112,11 @@ export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadat
},
} satisfies ColumnDefinition<ViewFieldTextMetadata>,
{
id: 'linkedin',
label: 'LinkedIn',
key: 'linkedin',
name: 'LinkedIn',
icon: <IconBrandLinkedin />,
size: 150,
order: 8,
index: 7,
metadata: {
type: 'url',
fieldName: 'linkedinUrl',
@ -124,11 +124,11 @@ export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadat
},
} satisfies ColumnDefinition<ViewFieldURLMetadata>,
{
id: 'x',
label: 'Twitter',
key: 'x',
name: 'Twitter',
icon: <IconBrandX />,
size: 150,
order: 9,
index: 8,
metadata: {
type: 'url',
fieldName: 'xUrl',

View File

@ -17,8 +17,8 @@ import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
export const pipelineAvailableFieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[] =
[
{
id: 'closeDate',
label: 'Close Date',
key: 'closeDate',
name: 'Close Date',
icon: <IconCalendarEvent />,
metadata: {
type: 'date',
@ -27,8 +27,8 @@ export const pipelineAvailableFieldDefinitions: ViewFieldDefinition<ViewFieldMet
isVisible: true,
} satisfies ViewFieldDefinition<ViewFieldDateMetadata>,
{
id: 'amount',
label: 'Amount',
key: 'amount',
name: 'Amount',
icon: <IconCurrencyDollar />,
metadata: {
type: 'number',
@ -37,8 +37,8 @@ export const pipelineAvailableFieldDefinitions: ViewFieldDefinition<ViewFieldMet
isVisible: true,
} satisfies ViewFieldDefinition<ViewFieldNumberMetadata>,
{
id: 'probability',
label: 'Probability',
key: 'probability',
name: 'Probability',
icon: <IconProgressCheck />,
metadata: {
type: 'probability',
@ -47,8 +47,8 @@ export const pipelineAvailableFieldDefinitions: ViewFieldDefinition<ViewFieldMet
isVisible: true,
} satisfies ViewFieldDefinition<ViewFieldProbabilityMetadata>,
{
id: 'pointOfContact',
label: 'Point of Contact',
key: 'pointOfContact',
name: 'Point of Contact',
icon: <IconUser />,
metadata: {
type: 'relation',

View File

@ -1,8 +1,8 @@
import { FieldMetadata, FieldType } from './FieldMetadata';
export type FieldDefinition<T extends FieldMetadata | unknown> = {
id: string;
label: string;
key: string;
name: string;
icon?: JSX.Element;
type: FieldType;
metadata: T;

View File

@ -116,8 +116,8 @@ export type ViewFieldMetadata = { type: ViewFieldType } & (
);
export type ViewFieldDefinition<T extends ViewFieldMetadata | unknown> = {
id: string;
label: string;
key: string;
name: string;
icon?: JSX.Element;
isVisible?: boolean;
metadata: T;

View File

@ -58,10 +58,10 @@ export const EntityTableColumnMenu = ({
<StyledDropdownMenuItemsContainer>
{hiddenColumns.map((column) => (
<DropdownMenuItem
key={column.id}
key={column.key}
actions={[
<IconButton
key={`add-${column.id}`}
key={`add-${column.key}`}
icon={<IconPlus size={theme.icon.size.sm} />}
onClick={() => handleAddColumn(column)}
/>,
@ -71,7 +71,7 @@ export const EntityTableColumnMenu = ({
cloneElement(column.icon, {
size: theme.icon.size.md,
})}
{column.label}
{column.name}
</DropdownMenuItem>
))}
</StyledDropdownMenuItemsContainer>

View File

@ -11,7 +11,7 @@ import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoi
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { resizeFieldOffsetState } from '../states/resizeFieldOffsetState';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { tableColumnsByIdScopedSelector } from '../states/selectors/tableColumnsByIdScopedSelector';
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
@ -76,8 +76,8 @@ export function EntityTableHeader() {
tableColumnsScopedState,
TableRecoilScopeContext,
);
const columnsById = useRecoilScopedValue(
tableColumnsByIdScopedSelector,
const columnsByKey = useRecoilScopedValue(
tableColumnsByKeyScopedSelector,
TableRecoilScopeContext,
);
const hiddenColumns = useRecoilScopedValue(
@ -92,7 +92,7 @@ export function EntityTableHeader() {
const [initialPointerPositionX, setInitialPointerPositionX] = useState<
number | null
>(null);
const [resizedFieldId, setResizedFieldId] = useState<string | null>(null);
const [resizedFieldKey, setResizedFieldKey] = useState<string | null>(null);
const [isColumnMenuOpen, setIsColumnMenuOpen] = useState(false);
const handleResizeHandlerStart = useCallback((positionX: number) => {
@ -110,19 +110,19 @@ export function EntityTableHeader() {
const handleResizeHandlerEnd = useRecoilCallback(
({ snapshot, set }) =>
() => {
if (!resizedFieldId) return;
if (!resizedFieldKey) return;
const nextWidth = Math.round(
Math.max(
columnsById[resizedFieldId].size +
columnsByKey[resizedFieldKey].size +
snapshot.getLoadable(resizeFieldOffsetState).valueOrThrow(),
COLUMN_MIN_WIDTH,
),
);
if (nextWidth !== columnsById[resizedFieldId].size) {
if (nextWidth !== columnsByKey[resizedFieldKey].size) {
const nextColumns = columns.map((column) =>
column.id === resizedFieldId
column.key === resizedFieldKey
? { ...column, size: nextWidth }
: column,
);
@ -132,13 +132,13 @@ export function EntityTableHeader() {
set(resizeFieldOffsetState, 0);
setInitialPointerPositionX(null);
setResizedFieldId(null);
setResizedFieldKey(null);
},
[resizedFieldId, columnsById, columns, setColumns],
[resizedFieldKey, columnsByKey, columns, setColumns],
);
useTrackPointer({
shouldTrackPointer: resizedFieldId !== null,
shouldTrackPointer: resizedFieldKey !== null,
onMouseDown: handleResizeHandlerStart,
onMouseMove: handleResizeHandlerMove,
onMouseUp: handleResizeHandlerEnd,
@ -163,20 +163,20 @@ export function EntityTableHeader() {
{visibleColumns.map((column) => (
<StyledColumnHeaderCell
key={column.id}
isResizing={resizedFieldId === column.id}
key={column.key}
isResizing={resizedFieldKey === column.key}
columnWidth={Math.max(
columnsById[column.id].size +
(resizedFieldId === column.id ? offset : 0),
columnsByKey[column.key].size +
(resizedFieldKey === column.key ? offset : 0),
COLUMN_MIN_WIDTH,
)}
>
<ColumnHead viewName={column.label} viewIcon={column.icon} />
<ColumnHead viewName={column.name} viewIcon={column.icon} />
<StyledResizeHandler
className="cursor-col-resize"
role="separator"
onPointerDown={() => {
setResizedFieldId(column.id);
setResizedFieldKey(column.key);
}}
/>
</StyledColumnHeaderCell>

View File

@ -33,7 +33,7 @@ export function EntityTableRow({ rowId }: { rowId: string }) {
</td>
{columns.map((column, columnIndex) => {
return (
<ColumnContext.Provider value={column} key={column.id}>
<ColumnContext.Provider value={column} key={column.key}>
<EntityTableCell cellIndex={columnIndex} />
</ColumnContext.Provider>
);

View File

@ -5,7 +5,7 @@ import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoi
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
import { tableColumnsByIdScopedSelector } from '../states/selectors/tableColumnsByIdScopedSelector';
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import type { ColumnDefinition } from '../types/ColumnDefinition';
@ -14,26 +14,26 @@ export const useTableColumns = () => {
tableColumnsScopedState,
TableRecoilScopeContext,
);
const tableColumnsById = useRecoilScopedValue(
tableColumnsByIdScopedSelector,
const tableColumnsByKey = useRecoilScopedValue(
tableColumnsByKeyScopedSelector,
TableRecoilScopeContext,
);
const handleColumnVisibilityChange = useCallback(
(column: ColumnDefinition<ViewFieldMetadata>) => {
const nextColumns = tableColumnsById[column.id]
const nextColumns = tableColumnsByKey[column.key]
? tableColumns.map((previousColumn) =>
previousColumn.id === column.id
previousColumn.key === column.key
? { ...previousColumn, isVisible: !column.isVisible }
: previousColumn,
)
: [...tableColumns, { ...column, isVisible: true }].sort(
(columnA, columnB) => columnA.order - columnB.order,
(columnA, columnB) => columnA.index - columnB.index,
);
setTableColumns(nextColumns);
},
[setTableColumns, tableColumns, tableColumnsById],
[setTableColumns, tableColumns, tableColumnsByKey],
);
return { handleColumnVisibilityChange };

View File

@ -95,7 +95,7 @@ export function TableOptionsDropdownContent({
!column.isVisible || visibleColumns.length > 1
? [
<IconButton
key={`action-${column.id}`}
key={`action-${column.key}`}
icon={
column.isVisible ? (
<IconMinus size={theme.icon.size.sm} />

View File

@ -31,12 +31,12 @@ export function TableOptionsDropdownSection({
<StyledDropdownMenuSubheader>{title}</StyledDropdownMenuSubheader>
<StyledDropdownMenuItemsContainer>
{columns.map((column) => (
<DropdownMenuItem key={column.id} actions={renderActions(column)}>
<DropdownMenuItem key={column.key} actions={renderActions(column)}>
{column.icon &&
cloneElement(column.icon, {
size: theme.icon.size.md,
})}
{column.label}
{column.name}
</DropdownMenuItem>
))}
</StyledDropdownMenuItemsContainer>

View File

@ -9,10 +9,10 @@ export const hiddenTableColumnsScopedSelector = selectorFamily({
(scopeId: string) =>
({ get }) => {
const columns = get(tableColumnsScopedState(scopeId));
const columnLabels = columns.map(({ label }) => label);
const columnKeys = columns.map(({ key }) => key);
const otherAvailableColumns = get(
availableTableColumnsScopedState(scopeId),
).filter(({ label }) => !columnLabels.includes(label));
).filter(({ key }) => !columnKeys.includes(key));
return [
...columns.filter((column) => !column.isVisible),

View File

@ -5,12 +5,12 @@ import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
import type { ColumnDefinition } from '../../types/ColumnDefinition';
import { savedTableColumnsScopedState } from '../savedTableColumnsScopedState';
export const savedTableColumnsByIdScopedSelector = selectorFamily({
key: 'savedTableColumnsByIdScopedSelector',
export const savedTableColumnsByKeyScopedSelector = selectorFamily({
key: 'savedTableColumnsByKeyScopedSelector',
get:
(viewId: string | undefined) =>
({ get }) =>
get(savedTableColumnsScopedState(viewId)).reduce<
Record<string, ColumnDefinition<ViewFieldMetadata>>
>((result, column) => ({ ...result, [column.id]: column }), {}),
>((result, column) => ({ ...result, [column.key]: column }), {}),
});

View File

@ -5,12 +5,12 @@ import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
import type { ColumnDefinition } from '../../types/ColumnDefinition';
import { tableColumnsScopedState } from '../tableColumnsScopedState';
export const tableColumnsByIdScopedSelector = selectorFamily({
key: 'tableColumnsByIdScopedSelector',
export const tableColumnsByKeyScopedSelector = selectorFamily({
key: 'tableColumnsByKeyScopedSelector',
get:
(scopeId: string) =>
({ get }) =>
get(tableColumnsScopedState(scopeId)).reduce<
Record<string, ColumnDefinition<ViewFieldMetadata>>
>((result, column) => ({ ...result, [column.id]: column }), {}),
>((result, column) => ({ ...result, [column.key]: column }), {}),
});

View File

@ -6,5 +6,5 @@ import type {
export type ColumnDefinition<T extends ViewFieldMetadata | unknown> =
ViewFieldDefinition<T> & {
size: number;
order: number;
index: number;
};

View File

@ -6,11 +6,11 @@ export const UPDATE_VIEW_FIELD = gql`
$where: ViewFieldWhereUniqueInput!
) {
updateOneViewField(data: $data, where: $where) {
id
fieldName
isVisible
sizeInPx
index
isVisible
key
name
size
}
}
`;

View File

@ -6,11 +6,11 @@ export const GET_VIEW_FIELDS = gql`
$orderBy: [ViewFieldOrderByWithRelationInput!]
) {
viewFields: findManyViewField(where: $where, orderBy: $orderBy) {
id
fieldName
isVisible
sizeInPx
index
isVisible
key
name
size
}
}
`;

View File

@ -8,7 +8,7 @@ import type {
import { availableTableColumnsScopedState } from '@/ui/table/states/availableTableColumnsScopedState';
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
import { savedTableColumnsScopedState } from '@/ui/table/states/savedTableColumnsScopedState';
import { savedTableColumnsByIdScopedSelector } from '@/ui/table/states/selectors/savedTableColumnsByIdScopedSelector';
import { savedTableColumnsByKeyScopedSelector } from '@/ui/table/states/selectors/savedTableColumnsByKeyScopedSelector';
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
import { currentTableViewIdState } from '@/ui/table/states/tableViewsState';
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
@ -29,21 +29,22 @@ const DEFAULT_VIEW_FIELD_METADATA: ViewFieldTextMetadata = {
};
const toViewFieldInput = (
objectName: 'company' | 'person',
objectId: 'company' | 'person',
fieldDefinition: ColumnDefinition<ViewFieldMetadata>,
) => ({
fieldName: fieldDefinition.label,
index: fieldDefinition.order,
key: fieldDefinition.key,
name: fieldDefinition.name,
index: fieldDefinition.index,
isVisible: fieldDefinition.isVisible ?? true,
objectName,
sizeInPx: fieldDefinition.size,
objectId,
size: fieldDefinition.size,
});
export const useTableViewFields = ({
objectName,
objectId,
columnDefinitions,
}: {
objectName: 'company' | 'person';
objectId: 'company' | 'person';
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
}) => {
const currentTableViewId = useRecoilScopedValue(
@ -62,8 +63,8 @@ export const useTableViewFields = ({
const setSavedTableColumns = useSetRecoilState(
savedTableColumnsScopedState(currentTableViewId),
);
const savedTableColumnsById = useRecoilValue(
savedTableColumnsByIdScopedSelector(currentTableViewId),
const savedTableColumnsByKey = useRecoilValue(
savedTableColumnsByKeyScopedSelector(currentTableViewId),
);
const [createViewFieldsMutation] = useCreateViewFieldsMutation();
@ -79,13 +80,13 @@ export const useTableViewFields = ({
return createViewFieldsMutation({
variables: {
data: columns.map((column) => ({
...toViewFieldInput(objectName, column),
...toViewFieldInput(objectId, column),
viewId,
})),
},
});
},
[createViewFieldsMutation, currentTableViewId, objectName],
[createViewFieldsMutation, currentTableViewId, objectId],
);
const updateViewFields = useCallback(
@ -98,9 +99,11 @@ export const useTableViewFields = ({
variables: {
data: {
isVisible: column.isVisible,
sizeInPx: column.size,
size: column.size,
},
where: {
viewId_key: { key: column.key, viewId: currentTableViewId },
},
where: { id: column.id },
},
}),
),
@ -114,8 +117,8 @@ export const useTableViewFields = ({
variables: {
orderBy: { index: SortOrder.Asc },
where: {
objectName: { equals: objectName },
viewId: { equals: currentTableViewId ?? null },
objectId: { equals: objectId },
viewId: { equals: currentTableViewId },
},
},
onCompleted: async (data) => {
@ -128,13 +131,13 @@ export const useTableViewFields = ({
const nextColumns = data.viewFields.map<
ColumnDefinition<ViewFieldMetadata>
>((viewField) => ({
...(columnDefinitions.find(
({ label: columnLabel }) => viewField.fieldName === columnLabel,
) || { metadata: DEFAULT_VIEW_FIELD_METADATA }),
id: viewField.id,
label: viewField.fieldName,
order: viewField.index,
size: viewField.sizeInPx,
...(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,
}));
@ -153,15 +156,15 @@ export const useTableViewFields = ({
if (!currentTableViewId) return;
const viewFieldsToCreate = tableColumns.filter(
(column) => !savedTableColumnsById[column.id],
(column) => !savedTableColumnsByKey[column.key],
);
await createViewFields(viewFieldsToCreate);
const viewFieldsToUpdate = tableColumns.filter(
(column) =>
savedTableColumnsById[column.id] &&
(savedTableColumnsById[column.id].size !== column.size ||
savedTableColumnsById[column.id].isVisible !== column.isVisible),
savedTableColumnsByKey[column.key] &&
(savedTableColumnsByKey[column.key].size !== column.size ||
savedTableColumnsByKey[column.key].isVisible !== column.isVisible),
);
await updateViewFields(viewFieldsToUpdate);
@ -170,7 +173,7 @@ export const useTableViewFields = ({
createViewFields,
currentTableViewId,
refetch,
savedTableColumnsById,
savedTableColumnsByKey,
tableColumns,
updateViewFields,
]);

View File

@ -45,7 +45,7 @@ export const useTableViews = <Entity, SortField>({
);
const { createViewFields, persistColumns } = useTableViewFields({
objectName: objectId,
objectId,
columnDefinitions,
});
const { createViewFilters, persistFilters } = useViewFilters({

View File

@ -95,7 +95,7 @@ export function CompanyShow() {
return (
<EditableFieldDefinitionContext.Provider
value={fieldDefinition}
key={fieldDefinition.id}
key={fieldDefinition.key}
>
<GenericEditableField />
</EditableFieldDefinitionContext.Provider>

View File

@ -21,8 +21,8 @@ import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
{
id: 'domainName',
label: 'Domain name',
key: 'domainName',
name: 'Domain name',
icon: <IconLink />,
type: 'url',
metadata: {
@ -31,8 +31,8 @@ export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldURLMetadata>,
{
id: 'accountOwner',
label: 'Account owner',
key: 'accountOwner',
name: 'Account owner',
icon: <IconUserCircle />,
type: 'relation',
metadata: {
@ -41,8 +41,8 @@ export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldRelationMetadata>,
{
id: 'employees',
label: 'Employees',
key: 'employees',
name: 'Employees',
icon: <IconUsers />,
type: 'number',
metadata: {
@ -51,8 +51,8 @@ export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldNumberMetadata>,
{
id: 'address',
label: 'Address',
key: 'address',
name: 'Address',
icon: <IconMap />,
type: 'text',
metadata: {
@ -61,8 +61,8 @@ export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldTextMetadata>,
{
id: 'createdAt',
label: 'Created at',
key: 'createdAt',
name: 'Created at',
icon: <IconCalendar />,
type: 'date',
metadata: {
@ -70,8 +70,8 @@ export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldDateMetadata>,
{
id: 'idealCustomerProfile',
label: 'ICP',
key: 'idealCustomerProfile',
name: 'ICP',
icon: <IconTarget />,
type: 'boolean',
metadata: {
@ -79,8 +79,8 @@ export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldBooleanMetadata>,
{
id: 'xUrl',
label: 'Twitter',
key: 'xUrl',
name: 'Twitter',
icon: <IconBrandX />,
type: 'url',
metadata: {

View File

@ -116,7 +116,7 @@ export function PersonShow() {
return (
<EditableFieldDefinitionContext.Provider
value={fieldDefinition}
key={fieldDefinition.id}
key={fieldDefinition.key}
>
<GenericEditableField />
</EditableFieldDefinitionContext.Provider>

View File

@ -21,8 +21,8 @@ import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
{
id: 'email',
label: 'Email',
key: 'email',
name: 'Email',
icon: <IconMail />,
type: 'text',
metadata: {
@ -31,8 +31,8 @@ export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldTextMetadata>,
{
id: 'company',
label: 'Company',
key: 'company',
name: 'Company',
icon: <IconBuildingSkyscraper />,
type: 'relation',
metadata: {
@ -42,8 +42,8 @@ export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldRelationMetadata>,
{
id: 'phone',
label: 'Phone',
key: 'phone',
name: 'Phone',
icon: <IconPhone />,
type: 'phone',
metadata: {
@ -52,8 +52,8 @@ export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldPhoneMetadata>,
{
id: 'createdAt',
label: 'Created at',
key: 'createdAt',
name: 'Created at',
icon: <IconCalendar />,
type: 'date',
metadata: {
@ -61,8 +61,8 @@ export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldDateMetadata>,
{
id: 'city',
label: 'City',
key: 'city',
name: 'City',
icon: <IconMap />,
type: 'text',
metadata: {
@ -71,8 +71,8 @@ export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldTextMetadata>,
{
id: 'jobTitle',
label: 'Job Title',
key: 'jobTitle',
name: 'Job Title',
icon: <IconBriefcase />,
type: 'text',
metadata: {
@ -81,8 +81,8 @@ export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldTextMetadata>,
{
id: 'linkedinUrl',
label: 'Linkedin URL',
key: 'linkedinUrl',
name: 'Linkedin URL',
icon: <IconBrandLinkedin />,
type: 'url',
metadata: {
@ -91,8 +91,8 @@ export const personShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
},
} satisfies FieldDefinition<FieldURLMetadata>,
{
id: 'xUrl',
label: 'X URL',
key: 'xUrl',
name: 'X URL',
icon: <IconBrandX />,
type: 'url',
metadata: {

View File

@ -32,12 +32,16 @@ import { mockedActivities, mockedTasks } from './mock-data/activities';
import {
mockedCompaniesData,
mockedCompanyViewFields,
mockedCompanyViews,
} from './mock-data/companies';
import { mockedPeopleData, mockedPersonViewFields } from './mock-data/people';
import {
mockedPeopleData,
mockedPersonViewFields,
mockedPersonViews,
} from './mock-data/people';
import { mockedPipelineProgressData } from './mock-data/pipeline-progress';
import { mockedPipelinesData } from './mock-data/pipelines';
import { mockedUsersData } from './mock-data/users';
import { mockedViews } from './mock-data/views';
import {
fetchOneFromData,
filterAndSortData,
@ -229,17 +233,30 @@ export const graphqlMocks = [
}),
);
}),
graphql.query(getOperationName(GET_VIEWS) ?? '', (req, res, ctx) => {
const {
where: {
objectId: { equals: objectId },
},
} = req.variables;
return res(
ctx.data({
views: objectId === 'company' ? mockedCompanyViews : mockedPersonViews,
}),
);
}),
graphql.query(getOperationName(GET_VIEW_FIELDS) ?? '', (req, res, ctx) => {
const {
where: {
objectName: { equals: objectName },
objectId: { equals: objectId },
},
} = req.variables;
return res(
ctx.data({
viewFields:
objectName === 'company'
objectId === 'company'
? mockedCompanyViewFields
: mockedPersonViewFields,
}),
@ -255,11 +272,4 @@ export const graphqlMocks = [
);
},
),
graphql.query(getOperationName(GET_VIEWS) ?? '', (req, res, ctx) => {
return res(
ctx.data({
views: mockedViews,
}),
);
}),
];

View File

@ -1,5 +1,5 @@
import { companiesAvailableColumnDefinitions } from '@/companies/constants/companiesAvailableColumnDefinitions';
import { Company, User, ViewField } from '~/generated/graphql';
import { Company, User, View, ViewField, ViewType } from '~/generated/graphql';
type MockedCompany = Pick<
Company,
@ -144,13 +144,25 @@ export const mockedCompaniesData: Array<MockedCompany> = [
},
];
export const mockedCompanyViewFields =
companiesAvailableColumnDefinitions.map<ViewField>((viewFieldDefinition) => ({
__typename: 'ViewField',
fieldName: viewFieldDefinition.label,
id: viewFieldDefinition.id,
index: viewFieldDefinition.order,
isVisible: true,
objectName: 'company',
sizeInPx: viewFieldDefinition.size,
}));
export const mockedCompanyViews: View[] = [
{
__typename: 'View',
id: 'e6a2232d-ca6c-42df-b78e-ca0343f545a9',
name: 'All companies',
objectId: 'company',
type: ViewType.Table,
},
];
export const mockedCompanyViewFields = companiesAvailableColumnDefinitions.map<
Omit<ViewField, 'view'>
>((viewFieldDefinition) => ({
__typename: 'ViewField',
name: viewFieldDefinition.name,
index: viewFieldDefinition.index,
isVisible: true,
key: viewFieldDefinition.key,
objectId: 'company',
size: viewFieldDefinition.size,
viewId: 'e6a2232d-ca6c-42df-b78e-ca0343f545a9',
}));

View File

@ -1,5 +1,11 @@
import { peopleAvailableColumnDefinitions } from '@/people/constants/peopleAvailableColumnDefinitions';
import { Company, Person, ViewField } from '~/generated/graphql';
import {
Company,
Person,
View,
ViewField,
ViewType,
} from '~/generated/graphql';
type RequiredAndNotNull<T> = {
[P in keyof T]-?: Exclude<T[P], null | undefined>;
@ -123,13 +129,32 @@ export const mockedPeopleData: MockedPerson[] = [
},
];
export const mockedPersonViewFields =
peopleAvailableColumnDefinitions.map<ViewField>((viewFieldDefinition) => ({
__typename: 'ViewField',
fieldName: viewFieldDefinition.label,
id: viewFieldDefinition.id,
index: viewFieldDefinition.order,
isVisible: true,
objectName: 'person',
sizeInPx: viewFieldDefinition.size,
}));
export const mockedPersonViews: View[] = [
{
__typename: 'View',
id: 'afd7737a-bf1d-41a3-8863-c277b56a657b',
name: 'All people',
objectId: 'person',
type: ViewType.Table,
},
{
__typename: 'View',
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230a',
name: 'View example 1',
objectId: 'person',
type: ViewType.Table,
},
];
export const mockedPersonViewFields = peopleAvailableColumnDefinitions.map<
Omit<ViewField, 'view'>
>((viewFieldDefinition) => ({
__typename: 'ViewField',
name: viewFieldDefinition.name,
index: viewFieldDefinition.index,
isVisible: true,
key: viewFieldDefinition.key,
objectId: 'person',
size: viewFieldDefinition.size,
viewId: 'afd7737a-bf1d-41a3-8863-c277b56a657b',
}));

View File

@ -1,14 +0,0 @@
import { View } from '~/generated/graphql';
type MockedView = Pick<View, 'id' | 'name'>;
export const mockedViews: Array<MockedView> = [
{
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230a',
name: 'All',
},
{
id: '89bb825c-171e-4bcc-9cf7-43448d6fb230a',
name: 'View example 1',
},
];

View File

@ -5,54 +5,44 @@
"type": "Table",
"fields": [
{
"fieldName": "Name",
"sizeInPx": 180,
"isVisible": true
"key": "name",
"name": "Name",
"size": 180
},
{
"fieldName": "URL",
"sizeInPx": 100,
"isVisible": true
"key": "domainName",
"name": "URL",
"size": 100
},
{
"fieldName": "Account Owner",
"sizeInPx": 150,
"isVisible": true
"key": "accountOwner",
"name": "Account Owner",
"size": 150
},
{
"fieldName": "Creation",
"sizeInPx": 150,
"isVisible": true
"key": "createdAt",
"name": "Creation",
"size": 150
},
{
"fieldName": "Employees",
"sizeInPx": 150,
"isVisible": true
"key": "employees",
"name": "Employees",
"size": 150
},
{
"fieldName": "LinkedIn",
"sizeInPx": 170,
"isVisible": true
"key": "linkedin",
"name": "LinkedIn",
"size": 170
},
{
"fieldName": "Address",
"sizeInPx": 170,
"isVisible": true
"key": "address",
"name": "Address",
"size": 170
},
{
"fieldName": "ICP",
"sizeInPx": 150,
"isVisible": false
},
{
"fieldName": "ARR",
"sizeInPx": 150,
"isVisible": true
},
{
"fieldName": "Twitter",
"sizeInPx": 150,
"isVisible": false
"key": "annualRecurringRevenue",
"name": "ARR",
"size": 150
}
]
},
@ -62,50 +52,50 @@
"type": "Table",
"fields": [
{
"fieldName": "People",
"sizeInPx": 210,
"isVisible": true
"key": "displayName",
"name": "People",
"size": 210
},
{
"fieldName": "Email",
"sizeInPx": 150,
"isVisible": true
"key": "email",
"name": "Email",
"size": 150
},
{
"fieldName": "Company",
"sizeInPx": 150,
"isVisible": true
"key": "company",
"name": "Company",
"size": 150
},
{
"fieldName": "Phone",
"sizeInPx": 150,
"isVisible": true
"key": "phone",
"name": "Phone",
"size": 150
},
{
"fieldName": "Creation",
"sizeInPx": 150,
"isVisible": true
"key": "createdAt",
"name": "Creation",
"size": 150
},
{
"fieldName": "City",
"sizeInPx": 150,
"isVisible": true
"key": "city",
"name": "City",
"size": 150
},
{
"fieldName": "Job title",
"sizeInPx": 150,
"isVisible": true
"key": "jobTitle",
"name": "Job title",
"size": 150
},
{
"fieldName": "LinkedIn",
"sizeInPx": 150,
"isVisible": true
"key": "linkedin",
"name": "LinkedIn",
"size": 150
},
{
"fieldName": "Twitter",
"sizeInPx": 150,
"isVisible": true
"key": "x",
"name": "Twitter",
"size": 150
}
]
}
]
]

View File

@ -55,8 +55,9 @@ export class ViewService {
await this.prismaService.client.viewField.createMany({
data: fields.map((viewField, index) => ({
...viewField,
objectName: view.objectId,
index: index + 1,
index,
isVisible: true,
objectId: view.objectId,
viewId: view.id,
workspaceId,
})),

View File

@ -0,0 +1,18 @@
/*
Warnings:
- The primary key for the `viewFields` table will be changed. If it partially fails, the table could be left without primary key constraint.
- You are about to drop the column `id` on the `viewFields` table. All the data in the column will be lost.
- Added the required column `key` to the `viewFields` table without a default value. This is not possible if the table is not empty.
- Made the column `viewId` on table `viewFields` required. This step will fail if there are existing NULL values in that column.
*/
-- DropIndex
DROP INDEX "viewFields_workspaceId_viewId_objectName_fieldName_key";
-- AlterTable
ALTER TABLE "viewFields" DROP CONSTRAINT "viewFields_pkey",
DROP COLUMN "id",
ADD COLUMN "key" TEXT NOT NULL,
ALTER COLUMN "viewId" SET NOT NULL,
ADD CONSTRAINT "viewFields_pkey" PRIMARY KEY ("viewId", "key");

View File

@ -0,0 +1,4 @@
-- AlterTable
ALTER TABLE "viewFields" RENAME COLUMN "fieldName" TO "name";
ALTER TABLE "viewFields" RENAME COLUMN "objectName" TO "objectId";
ALTER TABLE "viewFields" RENAME COLUMN "sizeInPx" TO "size";

View File

@ -657,24 +657,21 @@ model ViewSort {
}
model ViewField {
/// @Validator.IsString()
/// @Validator.IsOptional()
id String @id @default(uuid())
index Int
isVisible Boolean
key String
name String
objectId String
size Int
fieldName String
index Int
isVisible Boolean
objectName String
sizeInPx Int
view View? @relation(fields: [viewId], references: [id], onDelete: Cascade)
viewId String?
view View @relation(fields: [viewId], references: [id], onDelete: Cascade)
viewId String
/// @TypeGraphQL.omit(input: true, output: true)
workspace Workspace @relation(fields: [workspaceId], references: [id])
/// @TypeGraphQL.omit(input: true, output: true)
workspaceId String
@@unique([workspaceId, viewId, objectName, fieldName])
@@id([viewId, key])
@@map("viewFields")
}

View File

@ -20,73 +20,54 @@ export const seedViews = async (prisma: PrismaClient) => {
await Promise.all(
[
{
id: 'twenty-388833ba-1343-49d7-9092-065f92e0e5fa',
fieldName: 'Name',
sizeInPx: 180,
isVisible: true,
key: 'name',
name: 'Name',
size: 180,
},
{
id: 'twenty-fdbb7a60-18ac-4d52-83b8-399eb6055ec6',
fieldName: 'URL',
sizeInPx: 100,
isVisible: true,
key: 'domainName',
name: 'URL',
size: 100,
},
{
id: 'twenty-cc77beef-af99-4cd2-86dd-0230f8565ed5',
fieldName: 'Account Owner',
sizeInPx: 150,
isVisible: true,
key: 'accountOwner',
name: 'Account Owner',
size: 150,
},
{
id: 'twenty-28537b67-8b78-4885-903d-f749f34883b1',
fieldName: 'Creation',
sizeInPx: 150,
isVisible: true,
key: 'createdAt',
name: 'Creation',
size: 150,
},
{
id: 'twenty-59e6624d-9a4d-492d-a0f2-52f51f69d004',
fieldName: 'Employees',
sizeInPx: 150,
isVisible: true,
key: 'employees',
name: 'Employees',
size: 150,
},
{
id: 'twenty-2c4ee8b9-aacd-42dd-b422-22eca03aab5a',
fieldName: 'LinkedIn',
sizeInPx: 170,
isVisible: true,
key: 'linkedin',
name: 'LinkedIn',
size: 170,
},
{
id: 'twenty-b83e299f-7098-4748-a39e-431cca2907ab',
fieldName: 'Address',
sizeInPx: 170,
isVisible: true,
key: 'address',
name: 'Address',
size: 170,
},
{
id: 'twenty-acef1246-8461-4e34-96b9-f326d598d655',
fieldName: 'ICP',
sizeInPx: 150,
isVisible: false,
},
{
id: 'twenty-971828c5-8167-4997-ae13-3b7895faa6f2',
fieldName: 'ARR',
sizeInPx: 150,
isVisible: true,
},
{
id: 'twenty-90977d8a-328d-4f69-98e8-8c69723c5a18',
fieldName: 'Twitter',
sizeInPx: 150,
isVisible: false,
key: 'annualRecurringRevenue',
name: 'ARR',
size: 150,
},
].map((viewField, index) =>
prisma.viewField.upsert({
where: { id: viewField.id },
where: { viewId_key: { key: viewField.key, viewId: companyViewId } },
update: {},
create: {
...viewField,
index: index + 1,
objectName: 'company',
index,
isVisible: true,
objectId: 'company',
viewId: companyViewId,
workspaceId,
},
@ -109,67 +90,59 @@ export const seedViews = async (prisma: PrismaClient) => {
await Promise.all(
[
{
id: 'twenty-fc3461b4-661d-492e-8907-61004a41cca6',
fieldName: 'People',
sizeInPx: 210,
isVisible: true,
key: 'displayName',
name: 'People',
size: 210,
},
{
id: 'twenty-4724d413-4343-4528-b8c4-4431910722f8',
fieldName: 'Email',
sizeInPx: 150,
isVisible: true,
key: 'email',
name: 'Email',
size: 150,
},
{
id: 'twenty-fbb16b08-5a58-4a69-8bd0-a6d267994042',
fieldName: 'Company',
sizeInPx: 150,
isVisible: true,
key: 'company',
name: 'Company',
size: 150,
},
{
id: 'twenty-1bad57bb-6627-40f8-8c75-bb5902892273',
fieldName: 'Phone',
sizeInPx: 150,
isVisible: true,
key: 'phone',
name: 'Phone',
size: 150,
},
{
id: 'twenty-3544d797-740b-4e0b-8226-134bf38da256',
fieldName: 'Creation',
sizeInPx: 150,
isVisible: true,
key: 'createdAt',
name: 'Creation',
size: 150,
},
{
id: 'twenty-4b6d48fb-17e2-4071-8565-d512f84656d5',
fieldName: 'City',
sizeInPx: 150,
isVisible: true,
key: 'city',
name: 'City',
size: 150,
},
{
id: 'twenty-418849cc-aa5c-4835-822b-c0dfb076106b',
fieldName: 'Job title',
sizeInPx: 150,
isVisible: true,
key: 'jobTitle',
name: 'Job title',
size: 150,
},
{
id: 'twenty-7591af5d-e081-4afa-94bb-09bd0e517850',
fieldName: 'LinkedIn',
sizeInPx: 150,
isVisible: true,
key: 'linkedin',
name: 'LinkedIn',
size: 150,
},
{
id: 'twenty-e7baeb3d-8ef3-4e61-89d6-60f64b1d52c5',
fieldName: 'Twitter',
sizeInPx: 150,
isVisible: true,
key: 'x',
name: 'Twitter',
size: 150,
},
].map((viewField, index) =>
prisma.viewField.upsert({
where: { id: viewField.id },
where: { viewId_key: { key: viewField.key, viewId: personViewId } },
update: {},
create: {
...viewField,
index: index + 1,
objectName: 'person',
index,
isVisible: true,
objectId: 'person',
viewId: personViewId,
workspaceId,
},