mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-18 17:12:53 +03:00
refactor: add ColumnDefinition type (#1357)
* refactor: add ColumnDefinition type Closes #1193 * refactor: code review - rename things * fix: fix wrong import and lint
This commit is contained in:
parent
0d7b869274
commit
74919eff7a
@ -166,8 +166,8 @@ export function CompanyBoardCard() {
|
||||
<EditableFieldDefinitionContext.Provider
|
||||
value={{
|
||||
id: viewField.id,
|
||||
label: viewField.columnLabel,
|
||||
icon: viewField.columnIcon,
|
||||
label: viewField.label,
|
||||
icon: viewField.icon,
|
||||
type: viewField.metadata.type,
|
||||
metadata: viewField.metadata,
|
||||
}}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { pipelineViewFields } from '@/pipeline/constants/pipelineViewFields';
|
||||
import { pipelineAvailableFieldDefinitions } from '@/pipeline/constants/pipelineAvailableFieldDefinitions';
|
||||
import { useBoardActionBarEntries } from '@/ui/board/hooks/useBoardActionBarEntries';
|
||||
import { useBoardContextMenuEntries } from '@/ui/board/hooks/useBoardContextMenuEntries';
|
||||
import { isBoardLoadedState } from '@/ui/board/states/isBoardLoadedState';
|
||||
@ -44,7 +44,7 @@ export function HooksCompanyBoard({
|
||||
|
||||
useEffect(() => {
|
||||
setAvailableFilters(opportunitiesBoardOptions.filters);
|
||||
setFieldsDefinitionsState(pipelineViewFields);
|
||||
setFieldsDefinitionsState(pipelineAvailableFieldDefinitions);
|
||||
});
|
||||
|
||||
const [, setIsBoardLoaded] = useRecoilState(isBoardLoadedState);
|
||||
|
@ -0,0 +1,156 @@
|
||||
import type {
|
||||
ViewFieldBooleanMetadata,
|
||||
ViewFieldChipMetadata,
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldMetadata,
|
||||
ViewFieldMoneyMetadata,
|
||||
ViewFieldNumberMetadata,
|
||||
ViewFieldRelationMetadata,
|
||||
ViewFieldTextMetadata,
|
||||
ViewFieldURLMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import {
|
||||
IconBrandLinkedin,
|
||||
IconBrandX,
|
||||
IconBuildingSkyscraper,
|
||||
IconCalendarEvent,
|
||||
IconLink,
|
||||
IconMap,
|
||||
IconMoneybag,
|
||||
IconTarget,
|
||||
IconUserCircle,
|
||||
IconUsers,
|
||||
} from '@/ui/icon/index';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
|
||||
|
||||
export const companiesAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadata>[] =
|
||||
[
|
||||
{
|
||||
id: 'name',
|
||||
label: 'Name',
|
||||
icon: <IconBuildingSkyscraper />,
|
||||
size: 180,
|
||||
order: 1,
|
||||
metadata: {
|
||||
type: 'chip',
|
||||
urlFieldName: 'domainName',
|
||||
contentFieldName: 'name',
|
||||
relationType: Entity.Company,
|
||||
},
|
||||
isVisible: true,
|
||||
} as ColumnDefinition<ViewFieldChipMetadata>,
|
||||
{
|
||||
id: 'domainName',
|
||||
label: 'URL',
|
||||
icon: <IconLink />,
|
||||
size: 100,
|
||||
order: 2,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'domainName',
|
||||
placeHolder: 'example.com',
|
||||
},
|
||||
isVisible: true,
|
||||
} as ColumnDefinition<ViewFieldURLMetadata>,
|
||||
{
|
||||
id: 'accountOwner',
|
||||
label: 'Account Owner',
|
||||
icon: <IconUserCircle />,
|
||||
size: 150,
|
||||
order: 3,
|
||||
metadata: {
|
||||
type: 'relation',
|
||||
fieldName: 'accountOwner',
|
||||
relationType: Entity.User,
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ColumnDefinition<ViewFieldRelationMetadata>,
|
||||
{
|
||||
id: 'createdAt',
|
||||
label: 'Creation',
|
||||
icon: <IconCalendarEvent />,
|
||||
size: 150,
|
||||
order: 4,
|
||||
metadata: {
|
||||
type: 'date',
|
||||
fieldName: 'createdAt',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ColumnDefinition<ViewFieldDateMetadata>,
|
||||
{
|
||||
id: 'employees',
|
||||
label: 'Employees',
|
||||
icon: <IconUsers />,
|
||||
size: 150,
|
||||
order: 5,
|
||||
metadata: {
|
||||
type: 'number',
|
||||
fieldName: 'employees',
|
||||
isPositive: true,
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ColumnDefinition<ViewFieldNumberMetadata>,
|
||||
{
|
||||
id: 'linkedin',
|
||||
label: 'LinkedIn',
|
||||
icon: <IconBrandLinkedin />,
|
||||
size: 170,
|
||||
order: 6,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'linkedinUrl',
|
||||
placeHolder: 'LinkedIn URL',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ColumnDefinition<ViewFieldURLMetadata>,
|
||||
{
|
||||
id: 'address',
|
||||
label: 'Address',
|
||||
icon: <IconMap />,
|
||||
size: 170,
|
||||
order: 7,
|
||||
metadata: {
|
||||
type: 'text',
|
||||
fieldName: 'address',
|
||||
placeHolder: 'Address', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ColumnDefinition<ViewFieldTextMetadata>,
|
||||
{
|
||||
id: 'idealCustomerProfile',
|
||||
label: 'ICP',
|
||||
icon: <IconTarget />,
|
||||
size: 150,
|
||||
order: 8,
|
||||
metadata: {
|
||||
type: 'boolean',
|
||||
fieldName: 'idealCustomerProfile',
|
||||
},
|
||||
isVisible: false,
|
||||
} satisfies ColumnDefinition<ViewFieldBooleanMetadata>,
|
||||
{
|
||||
id: 'annualRecurringRevenue',
|
||||
label: 'ARR',
|
||||
icon: <IconMoneybag />,
|
||||
size: 150,
|
||||
order: 8,
|
||||
metadata: {
|
||||
type: 'moneyAmount',
|
||||
fieldName: 'annualRecurringRevenue',
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldMoneyMetadata>,
|
||||
{
|
||||
id: 'xUrl',
|
||||
label: 'Twitter',
|
||||
icon: <IconBrandX />,
|
||||
size: 150,
|
||||
order: 8,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'xUrl',
|
||||
placeHolder: 'X',
|
||||
},
|
||||
isVisible: false,
|
||||
} satisfies ColumnDefinition<ViewFieldURLMetadata>,
|
||||
];
|
@ -1,155 +0,0 @@
|
||||
import {
|
||||
ViewFieldBooleanMetadata,
|
||||
ViewFieldChipMetadata,
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
ViewFieldMoneyMetadata,
|
||||
ViewFieldNumberMetadata,
|
||||
ViewFieldRelationMetadata,
|
||||
ViewFieldTextMetadata,
|
||||
ViewFieldURLMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import {
|
||||
IconBrandLinkedin,
|
||||
IconBrandX,
|
||||
IconBuildingSkyscraper,
|
||||
IconCalendarEvent,
|
||||
IconLink,
|
||||
IconMap,
|
||||
IconMoneybag,
|
||||
IconTarget,
|
||||
IconUserCircle,
|
||||
IconUsers,
|
||||
} from '@/ui/icon/index';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
|
||||
export const companyViewFields: ViewFieldDefinition<ViewFieldMetadata>[] = [
|
||||
{
|
||||
id: 'name',
|
||||
columnLabel: 'Name',
|
||||
columnIcon: <IconBuildingSkyscraper />,
|
||||
columnSize: 180,
|
||||
columnOrder: 1,
|
||||
metadata: {
|
||||
type: 'chip',
|
||||
urlFieldName: 'domainName',
|
||||
contentFieldName: 'name',
|
||||
relationType: Entity.Company,
|
||||
},
|
||||
isVisible: true,
|
||||
} as ViewFieldDefinition<ViewFieldChipMetadata>,
|
||||
{
|
||||
id: 'domainName',
|
||||
columnLabel: 'URL',
|
||||
columnIcon: <IconLink />,
|
||||
columnSize: 100,
|
||||
columnOrder: 2,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'domainName',
|
||||
placeHolder: 'example.com',
|
||||
},
|
||||
isVisible: true,
|
||||
} as ViewFieldDefinition<ViewFieldURLMetadata>,
|
||||
{
|
||||
id: 'accountOwner',
|
||||
columnLabel: 'Account Owner',
|
||||
columnIcon: <IconUserCircle />,
|
||||
columnSize: 150,
|
||||
columnOrder: 3,
|
||||
metadata: {
|
||||
type: 'relation',
|
||||
fieldName: 'accountOwner',
|
||||
relationType: Entity.User,
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldRelationMetadata>,
|
||||
{
|
||||
id: 'createdAt',
|
||||
columnLabel: 'Creation',
|
||||
columnIcon: <IconCalendarEvent />,
|
||||
columnSize: 150,
|
||||
columnOrder: 4,
|
||||
metadata: {
|
||||
type: 'date',
|
||||
fieldName: 'createdAt',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldDateMetadata>,
|
||||
{
|
||||
id: 'employees',
|
||||
columnLabel: 'Employees',
|
||||
columnIcon: <IconUsers />,
|
||||
columnSize: 150,
|
||||
columnOrder: 5,
|
||||
metadata: {
|
||||
type: 'number',
|
||||
fieldName: 'employees',
|
||||
isPositive: true,
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldNumberMetadata>,
|
||||
{
|
||||
id: 'linkedin',
|
||||
columnLabel: 'LinkedIn',
|
||||
columnIcon: <IconBrandLinkedin />,
|
||||
columnSize: 170,
|
||||
columnOrder: 6,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'linkedinUrl',
|
||||
placeHolder: 'LinkedIn URL',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldURLMetadata>,
|
||||
{
|
||||
id: 'address',
|
||||
columnLabel: 'Address',
|
||||
columnIcon: <IconMap />,
|
||||
columnSize: 170,
|
||||
columnOrder: 7,
|
||||
metadata: {
|
||||
type: 'text',
|
||||
fieldName: 'address',
|
||||
placeHolder: 'Address', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldTextMetadata>,
|
||||
{
|
||||
id: 'idealCustomerProfile',
|
||||
columnLabel: 'ICP',
|
||||
columnIcon: <IconTarget />,
|
||||
columnSize: 150,
|
||||
columnOrder: 8,
|
||||
metadata: {
|
||||
type: 'boolean',
|
||||
fieldName: 'idealCustomerProfile',
|
||||
},
|
||||
isVisible: false,
|
||||
} satisfies ViewFieldDefinition<ViewFieldBooleanMetadata>,
|
||||
{
|
||||
id: 'annualRecurringRevenue',
|
||||
columnLabel: 'ARR',
|
||||
columnIcon: <IconMoneybag />,
|
||||
columnSize: 150,
|
||||
columnOrder: 8,
|
||||
metadata: {
|
||||
type: 'moneyAmount',
|
||||
fieldName: 'annualRecurringRevenue',
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldMoneyMetadata>,
|
||||
{
|
||||
id: 'xUrl',
|
||||
columnLabel: 'Twitter',
|
||||
columnIcon: <IconBrandX />,
|
||||
columnSize: 150,
|
||||
columnOrder: 8,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'xUrl',
|
||||
placeHolder: 'X',
|
||||
},
|
||||
isVisible: false,
|
||||
} satisfies ViewFieldDefinition<ViewFieldURLMetadata>,
|
||||
];
|
@ -1,4 +1,4 @@
|
||||
import { companyViewFields } from '@/companies/constants/companyViewFields';
|
||||
import { companiesAvailableColumnDefinitions } from '@/companies/constants/companiesAvailableColumnDefinitions';
|
||||
import { useCompanyTableActionBarEntries } from '@/companies/hooks/useCompanyTableActionBarEntries';
|
||||
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
|
||||
import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
|
||||
@ -36,7 +36,7 @@ export function CompanyTable() {
|
||||
availableFilters: companiesFilters,
|
||||
availableSorts,
|
||||
objectId: 'company',
|
||||
viewFieldDefinitions: companyViewFields,
|
||||
columnDefinitions: companiesAvailableColumnDefinitions,
|
||||
});
|
||||
|
||||
const { openCompanySpreadsheetImport } = useSpreadsheetCompanyImport();
|
||||
|
@ -5,7 +5,7 @@ import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts
|
||||
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
|
||||
import { companyViewFields } from '../../constants/companyViewFields';
|
||||
import { companiesAvailableColumnDefinitions } from '../../constants/companiesAvailableColumnDefinitions';
|
||||
|
||||
import { mockedCompaniesData } from './companies-mock-data';
|
||||
|
||||
@ -19,7 +19,7 @@ export function CompanyTableMockData() {
|
||||
useEffect(() => {
|
||||
setEntityTableData(mockedCompaniesData, []);
|
||||
|
||||
setColumns(companyViewFields);
|
||||
setColumns(companiesAvailableColumnDefinitions);
|
||||
}, [setColumns, setEntityTableData]);
|
||||
|
||||
return <></>;
|
||||
|
@ -0,0 +1,138 @@
|
||||
import type {
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDoubleTextChipMetadata,
|
||||
ViewFieldEmailMetadata,
|
||||
ViewFieldMetadata,
|
||||
ViewFieldPhoneMetadata,
|
||||
ViewFieldRelationMetadata,
|
||||
ViewFieldTextMetadata,
|
||||
ViewFieldURLMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import {
|
||||
IconBrandLinkedin,
|
||||
IconBrandX,
|
||||
IconBriefcase,
|
||||
IconBuildingSkyscraper,
|
||||
IconCalendarEvent,
|
||||
IconMail,
|
||||
IconMap,
|
||||
IconPhone,
|
||||
IconUser,
|
||||
} from '@/ui/icon/index';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
|
||||
|
||||
export const peopleAvailableColumnDefinitions: ColumnDefinition<ViewFieldMetadata>[] =
|
||||
[
|
||||
{
|
||||
id: 'displayName',
|
||||
label: 'People',
|
||||
icon: <IconUser />,
|
||||
size: 210,
|
||||
order: 1,
|
||||
metadata: {
|
||||
type: 'double-text-chip',
|
||||
firstValueFieldName: 'firstName',
|
||||
secondValueFieldName: 'lastName',
|
||||
firstValuePlaceholder: 'First name', // Hack: Fake character to prevent password-manager from filling the field
|
||||
secondValuePlaceholder: 'Last name', // Hack: Fake character to prevent password-manager from filling the field
|
||||
avatarUrlFieldName: 'avatarUrl',
|
||||
entityType: Entity.Person,
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldDoubleTextChipMetadata>,
|
||||
{
|
||||
id: 'email',
|
||||
label: 'Email',
|
||||
icon: <IconMail />,
|
||||
size: 150,
|
||||
order: 2,
|
||||
metadata: {
|
||||
type: 'email',
|
||||
fieldName: 'email',
|
||||
placeHolder: 'Email', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldEmailMetadata>,
|
||||
{
|
||||
id: 'company',
|
||||
label: 'Company',
|
||||
icon: <IconBuildingSkyscraper />,
|
||||
size: 150,
|
||||
order: 3,
|
||||
metadata: {
|
||||
type: 'relation',
|
||||
fieldName: 'company',
|
||||
relationType: Entity.Company,
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldRelationMetadata>,
|
||||
{
|
||||
id: 'phone',
|
||||
label: 'Phone',
|
||||
icon: <IconPhone />,
|
||||
size: 150,
|
||||
order: 4,
|
||||
metadata: {
|
||||
type: 'phone',
|
||||
fieldName: 'phone',
|
||||
placeHolder: 'Phone', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldPhoneMetadata>,
|
||||
{
|
||||
id: 'createdAt',
|
||||
label: 'Creation',
|
||||
icon: <IconCalendarEvent />,
|
||||
size: 150,
|
||||
order: 5,
|
||||
metadata: {
|
||||
type: 'date',
|
||||
fieldName: 'createdAt',
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldDateMetadata>,
|
||||
{
|
||||
id: 'city',
|
||||
label: 'City',
|
||||
icon: <IconMap />,
|
||||
size: 150,
|
||||
order: 6,
|
||||
metadata: {
|
||||
type: 'text',
|
||||
fieldName: 'city',
|
||||
placeHolder: 'City', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldTextMetadata>,
|
||||
{
|
||||
id: 'jobTitle',
|
||||
label: 'Job title',
|
||||
icon: <IconBriefcase />,
|
||||
size: 150,
|
||||
order: 7,
|
||||
metadata: {
|
||||
type: 'text',
|
||||
fieldName: 'jobTitle',
|
||||
placeHolder: 'Job title',
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldTextMetadata>,
|
||||
{
|
||||
id: 'linkedin',
|
||||
label: 'LinkedIn',
|
||||
icon: <IconBrandLinkedin />,
|
||||
size: 150,
|
||||
order: 8,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'linkedinUrl',
|
||||
placeHolder: 'LinkedIn',
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldURLMetadata>,
|
||||
{
|
||||
id: 'x',
|
||||
label: 'Twitter',
|
||||
icon: <IconBrandX />,
|
||||
size: 150,
|
||||
order: 9,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'xUrl',
|
||||
placeHolder: 'X',
|
||||
},
|
||||
} satisfies ColumnDefinition<ViewFieldURLMetadata>,
|
||||
];
|
@ -1,137 +0,0 @@
|
||||
import {
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDefinition,
|
||||
ViewFieldDoubleTextChipMetadata,
|
||||
ViewFieldEmailMetadata,
|
||||
ViewFieldMetadata,
|
||||
ViewFieldPhoneMetadata,
|
||||
ViewFieldRelationMetadata,
|
||||
ViewFieldTextMetadata,
|
||||
ViewFieldURLMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import {
|
||||
IconBrandLinkedin,
|
||||
IconBrandX,
|
||||
IconBriefcase,
|
||||
IconBuildingSkyscraper,
|
||||
IconCalendarEvent,
|
||||
IconMail,
|
||||
IconMap,
|
||||
IconPhone,
|
||||
IconUser,
|
||||
} from '@/ui/icon/index';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
|
||||
export const peopleViewFields: ViewFieldDefinition<ViewFieldMetadata>[] = [
|
||||
{
|
||||
id: 'displayName',
|
||||
columnLabel: 'People',
|
||||
columnIcon: <IconUser />,
|
||||
columnSize: 210,
|
||||
columnOrder: 1,
|
||||
metadata: {
|
||||
type: 'double-text-chip',
|
||||
firstValueFieldName: 'firstName',
|
||||
secondValueFieldName: 'lastName',
|
||||
firstValuePlaceholder: 'First name', // Hack: Fake character to prevent password-manager from filling the field
|
||||
secondValuePlaceholder: 'Last name', // Hack: Fake character to prevent password-manager from filling the field
|
||||
avatarUrlFieldName: 'avatarUrl',
|
||||
entityType: Entity.Person,
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldDoubleTextChipMetadata>,
|
||||
{
|
||||
id: 'email',
|
||||
columnLabel: 'Email',
|
||||
columnIcon: <IconMail />,
|
||||
columnSize: 150,
|
||||
columnOrder: 2,
|
||||
metadata: {
|
||||
type: 'email',
|
||||
fieldName: 'email',
|
||||
placeHolder: 'Email', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldEmailMetadata>,
|
||||
{
|
||||
id: 'company',
|
||||
columnLabel: 'Company',
|
||||
columnIcon: <IconBuildingSkyscraper />,
|
||||
columnSize: 150,
|
||||
columnOrder: 3,
|
||||
metadata: {
|
||||
type: 'relation',
|
||||
fieldName: 'company',
|
||||
relationType: Entity.Company,
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldRelationMetadata>,
|
||||
{
|
||||
id: 'phone',
|
||||
columnLabel: 'Phone',
|
||||
columnIcon: <IconPhone />,
|
||||
columnSize: 150,
|
||||
columnOrder: 4,
|
||||
metadata: {
|
||||
type: 'phone',
|
||||
fieldName: 'phone',
|
||||
placeHolder: 'Phone', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldPhoneMetadata>,
|
||||
{
|
||||
id: 'createdAt',
|
||||
columnLabel: 'Creation',
|
||||
columnIcon: <IconCalendarEvent />,
|
||||
columnSize: 150,
|
||||
columnOrder: 5,
|
||||
metadata: {
|
||||
type: 'date',
|
||||
fieldName: 'createdAt',
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldDateMetadata>,
|
||||
{
|
||||
id: 'city',
|
||||
columnLabel: 'City',
|
||||
columnIcon: <IconMap />,
|
||||
columnSize: 150,
|
||||
columnOrder: 6,
|
||||
metadata: {
|
||||
type: 'text',
|
||||
fieldName: 'city',
|
||||
placeHolder: 'City', // Hack: Fake character to prevent password-manager from filling the field
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldTextMetadata>,
|
||||
{
|
||||
id: 'jobTitle',
|
||||
columnLabel: 'Job title',
|
||||
columnIcon: <IconBriefcase />,
|
||||
columnSize: 150,
|
||||
columnOrder: 7,
|
||||
metadata: {
|
||||
type: 'text',
|
||||
fieldName: 'jobTitle',
|
||||
placeHolder: 'Job title',
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldTextMetadata>,
|
||||
{
|
||||
id: 'linkedin',
|
||||
columnLabel: 'LinkedIn',
|
||||
columnIcon: <IconBrandLinkedin />,
|
||||
columnSize: 150,
|
||||
columnOrder: 8,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'linkedinUrl',
|
||||
placeHolder: 'LinkedIn',
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldURLMetadata>,
|
||||
{
|
||||
id: 'x',
|
||||
columnLabel: 'Twitter',
|
||||
columnIcon: <IconBrandX />,
|
||||
columnSize: 150,
|
||||
columnOrder: 9,
|
||||
metadata: {
|
||||
type: 'url',
|
||||
fieldName: 'xUrl',
|
||||
placeHolder: 'X',
|
||||
},
|
||||
} satisfies ViewFieldDefinition<ViewFieldURLMetadata>,
|
||||
];
|
@ -1,4 +1,4 @@
|
||||
import { peopleViewFields } from '@/people/constants/peopleViewFields';
|
||||
import { peopleAvailableColumnDefinitions } from '@/people/constants/peopleAvailableColumnDefinitions';
|
||||
import { usePersonTableContextMenuEntries } from '@/people/hooks/usePeopleTableContextMenuEntries';
|
||||
import { usePersonTableActionBarEntries } from '@/people/hooks/usePersonTableActionBarEntries';
|
||||
import { useSpreadsheetPersonImport } from '@/people/hooks/useSpreadsheetPersonImport';
|
||||
@ -37,7 +37,7 @@ export function PeopleTable() {
|
||||
availableFilters: peopleFilters,
|
||||
availableSorts,
|
||||
objectId: 'person',
|
||||
viewFieldDefinitions: peopleViewFields,
|
||||
columnDefinitions: peopleAvailableColumnDefinitions,
|
||||
});
|
||||
|
||||
const { setContextMenuEntries } = usePersonTableContextMenuEntries();
|
||||
|
@ -0,0 +1,61 @@
|
||||
import {
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
ViewFieldNumberMetadata,
|
||||
ViewFieldProbabilityMetadata,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import {
|
||||
IconCalendarEvent,
|
||||
IconCurrencyDollar,
|
||||
IconProgressCheck,
|
||||
IconUser,
|
||||
} from '@/ui/icon';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
|
||||
export const pipelineAvailableFieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[] =
|
||||
[
|
||||
{
|
||||
id: 'closeDate',
|
||||
label: 'Close Date',
|
||||
icon: <IconCalendarEvent />,
|
||||
metadata: {
|
||||
type: 'date',
|
||||
fieldName: 'closeDate',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldDateMetadata>,
|
||||
{
|
||||
id: 'amount',
|
||||
label: 'Amount',
|
||||
icon: <IconCurrencyDollar />,
|
||||
metadata: {
|
||||
type: 'number',
|
||||
fieldName: 'amount',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldNumberMetadata>,
|
||||
{
|
||||
id: 'probability',
|
||||
label: 'Probability',
|
||||
icon: <IconProgressCheck />,
|
||||
metadata: {
|
||||
type: 'probability',
|
||||
fieldName: 'probability',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldProbabilityMetadata>,
|
||||
{
|
||||
id: 'pointOfContact',
|
||||
label: 'Point of Contact',
|
||||
icon: <IconUser />,
|
||||
metadata: {
|
||||
type: 'relation',
|
||||
fieldName: 'pointOfContact',
|
||||
relationType: Entity.Person,
|
||||
useEditButton: true,
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldRelationMetadata>,
|
||||
];
|
@ -1,68 +0,0 @@
|
||||
import {
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
ViewFieldNumberMetadata,
|
||||
ViewFieldProbabilityMetadata,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import {
|
||||
IconCalendarEvent,
|
||||
IconCurrencyDollar,
|
||||
IconProgressCheck,
|
||||
IconUser,
|
||||
} from '@/ui/icon';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
|
||||
export const pipelineViewFields: ViewFieldDefinition<ViewFieldMetadata>[] = [
|
||||
{
|
||||
id: 'closeDate',
|
||||
columnLabel: 'Close Date',
|
||||
columnIcon: <IconCalendarEvent />,
|
||||
columnSize: 150,
|
||||
columnOrder: 4,
|
||||
metadata: {
|
||||
type: 'date',
|
||||
fieldName: 'closeDate',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldDateMetadata>,
|
||||
{
|
||||
id: 'amount',
|
||||
columnLabel: 'Amount',
|
||||
columnIcon: <IconCurrencyDollar />,
|
||||
columnSize: 150,
|
||||
columnOrder: 4,
|
||||
metadata: {
|
||||
type: 'number',
|
||||
fieldName: 'amount',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldNumberMetadata>,
|
||||
{
|
||||
id: 'probability',
|
||||
columnLabel: 'Probability',
|
||||
columnIcon: <IconProgressCheck />,
|
||||
columnSize: 150,
|
||||
columnOrder: 4,
|
||||
metadata: {
|
||||
type: 'probability',
|
||||
fieldName: 'probability',
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldProbabilityMetadata>,
|
||||
{
|
||||
id: 'pointOfContact',
|
||||
columnLabel: 'Point of Contact',
|
||||
columnIcon: <IconUser />,
|
||||
columnSize: 150,
|
||||
columnOrder: 4,
|
||||
metadata: {
|
||||
type: 'relation',
|
||||
fieldName: 'pointOfContact',
|
||||
relationType: Entity.Person,
|
||||
useEditButton: true,
|
||||
},
|
||||
isVisible: true,
|
||||
} satisfies ViewFieldDefinition<ViewFieldRelationMetadata>,
|
||||
];
|
@ -117,11 +117,8 @@ export type ViewFieldMetadata = { type: ViewFieldType } & (
|
||||
|
||||
export type ViewFieldDefinition<T extends ViewFieldMetadata | unknown> = {
|
||||
id: string;
|
||||
columnLabel: string;
|
||||
columnSize: number;
|
||||
columnOrder: number;
|
||||
columnIcon?: JSX.Element;
|
||||
filterIcon?: JSX.Element;
|
||||
label: string;
|
||||
icon?: JSX.Element;
|
||||
isVisible?: boolean;
|
||||
metadata: T;
|
||||
};
|
||||
|
@ -5,8 +5,8 @@ import { contextMenuIsOpenState } from '@/ui/context-menu/states/contextMenuIsOp
|
||||
import { contextMenuPositionState } from '@/ui/context-menu/states/contextMenuPositionState';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
|
||||
import { ColumnContext } from '../contexts/ColumnContext';
|
||||
import { ColumnIndexContext } from '../contexts/ColumnIndexContext';
|
||||
import { ViewFieldContext } from '../contexts/ViewFieldContext';
|
||||
import { GenericEditableCell } from '../editable-cell/components/GenericEditableCell';
|
||||
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
|
||||
|
||||
@ -26,9 +26,9 @@ export function EntityTableCell({ cellIndex }: { cellIndex: number }) {
|
||||
setContextMenuOpenState(true);
|
||||
}
|
||||
|
||||
const viewField = useContext(ViewFieldContext);
|
||||
const columnDefinition = useContext(ColumnContext);
|
||||
|
||||
if (!viewField) {
|
||||
if (!columnDefinition) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ export function EntityTableCell({ cellIndex }: { cellIndex: number }) {
|
||||
<RecoilScope>
|
||||
<ColumnIndexContext.Provider value={cellIndex}>
|
||||
<td onContextMenu={(event) => handleContextMenu(event)}>
|
||||
<GenericEditableCell viewField={viewField} />
|
||||
<GenericEditableCell columnDefinition={columnDefinition} />
|
||||
</td>
|
||||
</ColumnIndexContext.Provider>
|
||||
</RecoilScope>
|
||||
|
@ -53,11 +53,11 @@ export const EntityTableColumnMenu = ({
|
||||
/>,
|
||||
]}
|
||||
>
|
||||
{column.columnIcon &&
|
||||
cloneElement(column.columnIcon, {
|
||||
{column.icon &&
|
||||
cloneElement(column.icon, {
|
||||
size: theme.icon.size.md,
|
||||
})}
|
||||
{column.columnLabel}
|
||||
{column.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</StyledDropdownMenuItemsContainer>
|
||||
|
@ -114,16 +114,16 @@ export function EntityTableHeader() {
|
||||
|
||||
const nextWidth = Math.round(
|
||||
Math.max(
|
||||
columnsById[resizedFieldId].columnSize +
|
||||
columnsById[resizedFieldId].size +
|
||||
snapshot.getLoadable(resizeFieldOffsetState).valueOrThrow(),
|
||||
COLUMN_MIN_WIDTH,
|
||||
),
|
||||
);
|
||||
|
||||
if (nextWidth !== columnsById[resizedFieldId].columnSize) {
|
||||
if (nextWidth !== columnsById[resizedFieldId].size) {
|
||||
const nextColumns = columns.map((column) =>
|
||||
column.id === resizedFieldId
|
||||
? { ...column, columnSize: nextWidth }
|
||||
? { ...column, size: nextWidth }
|
||||
: column,
|
||||
);
|
||||
|
||||
@ -179,15 +179,12 @@ export function EntityTableHeader() {
|
||||
key={column.id}
|
||||
isResizing={resizedFieldId === column.id}
|
||||
columnWidth={Math.max(
|
||||
columnsById[column.id].columnSize +
|
||||
columnsById[column.id].size +
|
||||
(resizedFieldId === column.id ? offset : 0),
|
||||
COLUMN_MIN_WIDTH,
|
||||
)}
|
||||
>
|
||||
<ColumnHead
|
||||
viewName={column.columnLabel}
|
||||
viewIcon={column.columnIcon}
|
||||
/>
|
||||
<ColumnHead viewName={column.label} viewIcon={column.icon} />
|
||||
<StyledResizeHandler
|
||||
className="cursor-col-resize"
|
||||
role="separator"
|
||||
|
@ -2,7 +2,7 @@ import styled from '@emotion/styled';
|
||||
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
|
||||
import { ViewFieldContext } from '../contexts/ViewFieldContext';
|
||||
import { ColumnContext } from '../contexts/ColumnContext';
|
||||
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
|
||||
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
|
||||
@ -33,9 +33,9 @@ export function EntityTableRow({ rowId }: { rowId: string }) {
|
||||
</td>
|
||||
{columns.map((column, columnIndex) => {
|
||||
return (
|
||||
<ViewFieldContext.Provider value={column} key={column.id}>
|
||||
<ColumnContext.Provider value={column} key={column.id}>
|
||||
<EntityTableCell cellIndex={columnIndex} />
|
||||
</ViewFieldContext.Provider>
|
||||
</ColumnContext.Provider>
|
||||
);
|
||||
})}
|
||||
<td></td>
|
||||
|
8
front/src/modules/ui/table/contexts/ColumnContext.ts
Normal file
8
front/src/modules/ui/table/contexts/ColumnContext.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
import { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
export const ColumnContext =
|
||||
createContext<ColumnDefinition<ViewFieldMetadata> | null>(null);
|
@ -1,9 +0,0 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '../../editable-field/types/ViewField';
|
||||
|
||||
export const ViewFieldContext =
|
||||
createContext<ViewFieldDefinition<ViewFieldMetadata> | null>(null);
|
@ -1,4 +1,5 @@
|
||||
import { isViewFieldBoolean } from '@/ui/editable-field/types/guards/isViewFieldBoolean';
|
||||
import { isViewFieldChip } from '@/ui/editable-field/types/guards/isViewFieldChip';
|
||||
import { isViewFieldDate } from '@/ui/editable-field/types/guards/isViewFieldDate';
|
||||
import { isViewFieldDoubleText } from '@/ui/editable-field/types/guards/isViewFieldDoubleText';
|
||||
import { isViewFieldDoubleTextChip } from '@/ui/editable-field/types/guards/isViewFieldDoubleTextChip';
|
||||
@ -9,12 +10,9 @@ import { isViewFieldPhone } from '@/ui/editable-field/types/guards/isViewFieldPh
|
||||
import { isViewFieldRelation } from '@/ui/editable-field/types/guards/isViewFieldRelation';
|
||||
import { isViewFieldText } from '@/ui/editable-field/types/guards/isViewFieldText';
|
||||
import { isViewFieldURL } from '@/ui/editable-field/types/guards/isViewFieldURL';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import { isViewFieldChip } from '../../../editable-field/types/guards/isViewFieldChip';
|
||||
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
import { GenericEditableBooleanCell } from '../type/components/GenericEditableBooleanCell';
|
||||
import { GenericEditableChipCell } from '../type/components/GenericEditableChipCell';
|
||||
import { GenericEditableDateCell } from '../type/components/GenericEditableDateCell';
|
||||
@ -29,37 +27,41 @@ import { GenericEditableTextCell } from '../type/components/GenericEditableTextC
|
||||
import { GenericEditableURLCell } from '../type/components/GenericEditableURLCell';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableCell({ viewField: fieldDefinition }: OwnProps) {
|
||||
if (isViewFieldEmail(fieldDefinition)) {
|
||||
return <GenericEditableEmailCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldText(fieldDefinition)) {
|
||||
return <GenericEditableTextCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldRelation(fieldDefinition)) {
|
||||
return <GenericEditableRelationCell fieldDefinition={fieldDefinition} />;
|
||||
} else if (isViewFieldDoubleTextChip(fieldDefinition)) {
|
||||
return <GenericEditableDoubleTextChipCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldDoubleText(fieldDefinition)) {
|
||||
return <GenericEditableDoubleTextCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldPhone(fieldDefinition)) {
|
||||
return <GenericEditablePhoneCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldURL(fieldDefinition)) {
|
||||
return <GenericEditableURLCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldDate(fieldDefinition)) {
|
||||
return <GenericEditableDateCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldNumber(fieldDefinition)) {
|
||||
return <GenericEditableNumberCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldBoolean(fieldDefinition)) {
|
||||
return <GenericEditableBooleanCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldChip(fieldDefinition)) {
|
||||
return <GenericEditableChipCell viewField={fieldDefinition} />;
|
||||
} else if (isViewFieldMoney(fieldDefinition)) {
|
||||
return <GenericEditableMoneyCell viewField={fieldDefinition} />;
|
||||
export function GenericEditableCell({ columnDefinition }: OwnProps) {
|
||||
if (isViewFieldEmail(columnDefinition)) {
|
||||
return <GenericEditableEmailCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldText(columnDefinition)) {
|
||||
return <GenericEditableTextCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldRelation(columnDefinition)) {
|
||||
return <GenericEditableRelationCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldDoubleTextChip(columnDefinition)) {
|
||||
return (
|
||||
<GenericEditableDoubleTextChipCell columnDefinition={columnDefinition} />
|
||||
);
|
||||
} else if (isViewFieldDoubleText(columnDefinition)) {
|
||||
return (
|
||||
<GenericEditableDoubleTextCell columnDefinition={columnDefinition} />
|
||||
);
|
||||
} else if (isViewFieldPhone(columnDefinition)) {
|
||||
return <GenericEditablePhoneCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldURL(columnDefinition)) {
|
||||
return <GenericEditableURLCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldDate(columnDefinition)) {
|
||||
return <GenericEditableDateCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldNumber(columnDefinition)) {
|
||||
return <GenericEditableNumberCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldBoolean(columnDefinition)) {
|
||||
return <GenericEditableBooleanCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldChip(columnDefinition)) {
|
||||
return <GenericEditableChipCell columnDefinition={columnDefinition} />;
|
||||
} else if (isViewFieldMoney(columnDefinition)) {
|
||||
return <GenericEditableMoneyCell columnDefinition={columnDefinition} />;
|
||||
} else {
|
||||
console.warn(
|
||||
`Unknown field metadata type: ${fieldDefinition.metadata.type} in GenericEditableCell`,
|
||||
`Unknown field metadata type: ${columnDefinition.metadata.type} in GenericEditableCell`,
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
|
@ -2,18 +2,16 @@ import styled from '@emotion/styled';
|
||||
import { IconCheck, IconX } from '@tabler/icons-react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldBooleanMetadata,
|
||||
ViewFieldDefinition,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldBooleanMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
import { EditableCellDisplayContainer } from '../../components/EditableCellContainer';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldBooleanMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldBooleanMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
@ -36,13 +34,13 @@ function capitalizeFirstLetter(value: string) {
|
||||
return value.charAt(0).toUpperCase() + value.slice(1);
|
||||
}
|
||||
|
||||
export function GenericEditableBooleanCell({ viewField }: OwnProps) {
|
||||
export function GenericEditableBooleanCell({ columnDefinition }: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const [fieldValue, setFieldValue] = useRecoilState<boolean>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -54,7 +52,7 @@ export function GenericEditableBooleanCell({ viewField }: OwnProps) {
|
||||
setFieldValue(newValue);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, newValue);
|
||||
updateField(currentRowEntityId, columnDefinition, newValue);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
|
@ -1,30 +1,31 @@
|
||||
import {
|
||||
ViewFieldChipMetadata,
|
||||
ViewFieldDefinition,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldChipMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableChipCellDisplayMode } from './GenericEditableChipCellDisplayMode';
|
||||
import { GenericEditableChipCellEditMode } from './GenericEditableChipCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldChipMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldChipMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableChipCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
return (
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableChipCellEditMode viewField={viewField} />
|
||||
<GenericEditableChipCellEditMode columnDefinition={columnDefinition} />
|
||||
}
|
||||
nonEditModeContent={
|
||||
<GenericEditableChipCellDisplayMode fieldDefinition={viewField} />
|
||||
<GenericEditableChipCellDisplayMode
|
||||
columnDefinition={columnDefinition}
|
||||
/>
|
||||
}
|
||||
></EditableCell>
|
||||
);
|
||||
|
@ -1,39 +1,38 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||
import {
|
||||
ViewFieldChipMetadata,
|
||||
ViewFieldDefinition,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldChipMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
type OwnProps = {
|
||||
fieldDefinition: ViewFieldDefinition<ViewFieldChipMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldChipMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableChipCellDisplayMode({
|
||||
fieldDefinition,
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const content = useRecoilValue<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldDefinition.metadata.contentFieldName,
|
||||
fieldName: columnDefinition.metadata.contentFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const chipUrl = useRecoilValue<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldDefinition.metadata.urlFieldName,
|
||||
fieldName: columnDefinition.metadata.urlFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
switch (fieldDefinition.metadata.relationType) {
|
||||
switch (columnDefinition.metadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyChip
|
||||
@ -45,7 +44,7 @@ export function GenericEditableChipCellDisplayMode({
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${fieldDefinition.metadata.relationType}" in GenericEditableChipCellEditMode`,
|
||||
`Unknown relation type: "${columnDefinition.metadata.relationType}" in GenericEditableChipCellEditMode`,
|
||||
);
|
||||
return <> </>;
|
||||
}
|
||||
|
@ -1,27 +1,28 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldChipMetadata,
|
||||
ViewFieldDefinition,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldChipMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { TextCellEdit } from './TextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldChipMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldChipMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableChipCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableChipCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.contentFieldName,
|
||||
fieldName: columnDefinition.metadata.contentFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -33,13 +34,13 @@ export function GenericEditableChipCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(newText);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, newText);
|
||||
updateField(currentRowEntityId, columnDefinition, newText);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<TextCellEdit
|
||||
placeholder={viewField.metadata.placeHolder ?? ''}
|
||||
placeholder={columnDefinition.metadata.placeHolder ?? ''}
|
||||
autoFocus
|
||||
value={fieldValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDefinition,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldDateMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { DateInputDisplay } from '@/ui/input/date/components/DateInputDisplay';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableDateCellEditMode } from './GenericEditableDateCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldDateMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldDateMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
export function GenericEditableDateCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
@ -25,7 +24,7 @@ export function GenericEditableDateCell({
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -33,7 +32,7 @@ export function GenericEditableDateCell({
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableDateCellEditMode viewField={viewField} />
|
||||
<GenericEditableDateCellEditMode columnDefinition={columnDefinition} />
|
||||
}
|
||||
nonEditModeContent={<DateInputDisplay value={fieldValue} />}
|
||||
></EditableCell>
|
||||
|
@ -1,28 +1,29 @@
|
||||
import { DateTime } from 'luxon';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDefinition,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldDateMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { DateCellEdit } from './DateCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldDateMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldDateMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableDateCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableDateCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -40,7 +41,7 @@ export function GenericEditableDateCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(newDateISO);
|
||||
|
||||
if (currentRowEntityId && updateField && newDateISO) {
|
||||
updateField(currentRowEntityId, viewField, newDateISO);
|
||||
updateField(currentRowEntityId, columnDefinition, newDateISO);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,34 +1,33 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldDoubleTextMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldDoubleTextMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { TextInputDisplay } from '@/ui/input/text/components/TextInputDisplay';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableDoubleTextCellEditMode } from './GenericEditableDoubleTextCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldDoubleTextMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldDoubleTextMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableDoubleTextCell({ viewField }: OwnProps) {
|
||||
export function GenericEditableDoubleTextCell({ columnDefinition }: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const firstValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.firstValueFieldName,
|
||||
fieldName: columnDefinition.metadata.firstValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const secondValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.secondValueFieldName,
|
||||
fieldName: columnDefinition.metadata.secondValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -37,7 +36,9 @@ export function GenericEditableDoubleTextCell({ viewField }: OwnProps) {
|
||||
return (
|
||||
<EditableCell
|
||||
editModeContent={
|
||||
<GenericEditableDoubleTextCellEditMode viewField={viewField} />
|
||||
<GenericEditableDoubleTextCellEditMode
|
||||
columnDefinition={columnDefinition}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={<TextInputDisplay>{displayName}</TextInputDisplay>}
|
||||
></EditableCell>
|
||||
|
@ -1,34 +1,35 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldDoubleTextMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldDoubleTextMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { DoubleTextCellEdit } from './DoubleTextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldDoubleTextMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldDoubleTextMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableDoubleTextCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableDoubleTextCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [firstValue, setFirstValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.firstValueFieldName,
|
||||
fieldName: columnDefinition.metadata.firstValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const [secondValue, setSecondValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.secondValueFieldName,
|
||||
fieldName: columnDefinition.metadata.secondValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -41,7 +42,7 @@ export function GenericEditableDoubleTextCellEditMode({ viewField }: OwnProps) {
|
||||
setSecondValue(newSecondValue);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, {
|
||||
updateField(currentRowEntityId, columnDefinition, {
|
||||
firstValue: newFirstValue,
|
||||
secondValue: newSecondValue,
|
||||
});
|
||||
@ -50,8 +51,8 @@ export function GenericEditableDoubleTextCellEditMode({ viewField }: OwnProps) {
|
||||
|
||||
return (
|
||||
<DoubleTextCellEdit
|
||||
firstValuePlaceholder={viewField.metadata.firstValuePlaceholder}
|
||||
secondValuePlaceholder={viewField.metadata.secondValuePlaceholder}
|
||||
firstValuePlaceholder={columnDefinition.metadata.firstValuePlaceholder}
|
||||
secondValuePlaceholder={columnDefinition.metadata.secondValuePlaceholder}
|
||||
firstValue={firstValue ?? ''}
|
||||
secondValue={secondValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
|
@ -1,26 +1,31 @@
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldDoubleTextChipMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldDoubleTextChipMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { TableHotkeyScope } from '@/ui/table/types/TableHotkeyScope';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableDoubleTextChipCellDisplayMode } from './GenericEditableDoubleTextChipCellDisplayMode';
|
||||
import { GenericEditableDoubleTextChipCellEditMode } from './GenericEditableDoubleTextChipCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldDoubleTextChipMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldDoubleTextChipMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableDoubleTextChipCell({ viewField }: OwnProps) {
|
||||
export function GenericEditableDoubleTextChipCell({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
return (
|
||||
<EditableCell
|
||||
editHotkeyScope={{ scope: TableHotkeyScope.CellDoubleTextInput }}
|
||||
editModeContent={
|
||||
<GenericEditableDoubleTextChipCellEditMode viewField={viewField} />
|
||||
<GenericEditableDoubleTextChipCellEditMode
|
||||
columnDefinition={columnDefinition}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={
|
||||
<GenericEditableDoubleTextChipCellDisplayMode viewField={viewField} />
|
||||
<GenericEditableDoubleTextChipCellDisplayMode
|
||||
columnDefinition={columnDefinition}
|
||||
/>
|
||||
}
|
||||
></EditableCell>
|
||||
);
|
||||
|
@ -2,48 +2,47 @@ import { useRecoilState } from 'recoil';
|
||||
|
||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||
import { PersonChip } from '@/people/components/PersonChip';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldDoubleTextChipMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldDoubleTextChipMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldDoubleTextChipMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldDoubleTextChipMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableDoubleTextChipCellDisplayMode({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const [firstValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.firstValueFieldName,
|
||||
fieldName: columnDefinition.metadata.firstValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const [secondValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.secondValueFieldName,
|
||||
fieldName: columnDefinition.metadata.secondValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const [avatarUrlValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.avatarUrlFieldName,
|
||||
fieldName: columnDefinition.metadata.avatarUrlFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const displayName =
|
||||
firstValue || secondValue ? `${firstValue} ${secondValue}` : ' ';
|
||||
|
||||
switch (viewField.metadata.entityType) {
|
||||
switch (columnDefinition.metadata.entityType) {
|
||||
case Entity.Company: {
|
||||
return <CompanyChip id={currentRowEntityId ?? ''} name={displayName} />;
|
||||
}
|
||||
@ -58,7 +57,7 @@ export function GenericEditableDoubleTextChipCellDisplayMode({
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${viewField.metadata.entityType}" in GenericEditableDoubleTextChipCellDisplayMode`,
|
||||
`Unknown relation type: "${columnDefinition.metadata.entityType}" in GenericEditableDoubleTextChipCellDisplayMode`,
|
||||
);
|
||||
return <> </>;
|
||||
}
|
||||
|
@ -1,21 +1,20 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldDoubleTextChipMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldDoubleTextChipMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { DoubleTextCellEdit } from './DoubleTextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldDoubleTextChipMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldDoubleTextChipMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableDoubleTextChipCellEditMode({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
@ -23,14 +22,14 @@ export function GenericEditableDoubleTextChipCellEditMode({
|
||||
const [firstValue, setFirstValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.firstValueFieldName,
|
||||
fieldName: columnDefinition.metadata.firstValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const [secondValue, setSecondValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.secondValueFieldName,
|
||||
fieldName: columnDefinition.metadata.secondValueFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -53,7 +52,7 @@ export function GenericEditableDoubleTextChipCellEditMode({
|
||||
updateField &&
|
||||
(firstValueChanged || secondValueChanged)
|
||||
) {
|
||||
updateField(currentRowEntityId, viewField, {
|
||||
updateField(currentRowEntityId, columnDefinition, {
|
||||
firstValue: firstValueChanged ? newFirstValue : firstValue,
|
||||
secondValue: secondValueChanged ? newSecondValue : secondValue,
|
||||
});
|
||||
@ -62,8 +61,8 @@ export function GenericEditableDoubleTextChipCellEditMode({
|
||||
|
||||
return (
|
||||
<DoubleTextCellEdit
|
||||
firstValuePlaceholder={viewField.metadata.firstValuePlaceholder}
|
||||
secondValuePlaceholder={viewField.metadata.secondValuePlaceholder}
|
||||
firstValuePlaceholder={columnDefinition.metadata.firstValuePlaceholder}
|
||||
secondValuePlaceholder={columnDefinition.metadata.secondValuePlaceholder}
|
||||
firstValue={firstValue ?? ''}
|
||||
secondValue={secondValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldEmailMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldEmailMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { EmailInputDisplay } from '@/ui/input/email/components/EmailInputDisplay';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableEmailCellEditMode } from './GenericEditableEmailCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldEmailMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldEmailMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
export function GenericEditableEmailCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
@ -25,7 +24,7 @@ export function GenericEditableEmailCell({
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -33,7 +32,7 @@ export function GenericEditableEmailCell({
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableEmailCellEditMode viewField={viewField} />
|
||||
<GenericEditableEmailCellEditMode columnDefinition={columnDefinition} />
|
||||
}
|
||||
nonEditModeContent={<EmailInputDisplay value={fieldValue} />}
|
||||
></EditableCell>
|
||||
|
@ -1,27 +1,28 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldEmailMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldEmailMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { TextCellEdit } from './TextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldEmailMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldEmailMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableEmailCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableEmailCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -33,13 +34,13 @@ export function GenericEditableEmailCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(newEmail);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, newEmail);
|
||||
updateField(currentRowEntityId, columnDefinition, newEmail);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<TextCellEdit
|
||||
placeholder={viewField.metadata.placeHolder ?? ''}
|
||||
placeholder={columnDefinition.metadata.placeHolder ?? ''}
|
||||
autoFocus
|
||||
value={fieldValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
|
@ -1,17 +1,16 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMoneyMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMoneyMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableMoneyCellEditMode } from './GenericEditableMoneyCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldMoneyMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldMoneyMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
@ -21,7 +20,7 @@ function formatNumber(value: number) {
|
||||
}
|
||||
|
||||
export function GenericEditableMoneyCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
@ -29,7 +28,7 @@ export function GenericEditableMoneyCell({
|
||||
const fieldValue = useRecoilValue<number>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -37,7 +36,7 @@ export function GenericEditableMoneyCell({
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableMoneyCellEditMode viewField={viewField} />
|
||||
<GenericEditableMoneyCellEditMode columnDefinition={columnDefinition} />
|
||||
}
|
||||
nonEditModeContent={
|
||||
<>{fieldValue ? `$${formatNumber(fieldValue)}` : ''}</>
|
||||
|
@ -1,26 +1,27 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMoneyMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMoneyMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { TextCellEdit } from './TextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldMoneyMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldMoneyMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableMoneyCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableMoneyCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -43,7 +44,7 @@ export function GenericEditableMoneyCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(numberValue.toString());
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, numberValue);
|
||||
updateField(currentRowEntityId, columnDefinition, numberValue);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
|
@ -1,22 +1,21 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldNumberMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldNumberMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableNumberCellEditMode } from './GenericEditableNumberCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldNumberMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldNumberMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
export function GenericEditableNumberCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
@ -24,7 +23,7 @@ export function GenericEditableNumberCell({
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -32,7 +31,9 @@ export function GenericEditableNumberCell({
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableNumberCellEditMode viewField={viewField} />
|
||||
<GenericEditableNumberCellEditMode
|
||||
columnDefinition={columnDefinition}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={<>{fieldValue}</>}
|
||||
></EditableCell>
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldNumberMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldNumberMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
@ -12,20 +9,24 @@ import {
|
||||
castAsPositiveIntegerOrNull,
|
||||
} from '~/utils/cast-as-positive-integer-or-null';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { TextCellEdit } from './TextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldNumberMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldNumberMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableNumberCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableNumberCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -41,7 +42,7 @@ export function GenericEditableNumberCellEditMode({ viewField }: OwnProps) {
|
||||
throw new Error('Not a number');
|
||||
}
|
||||
|
||||
if (viewField.metadata.isPositive) {
|
||||
if (columnDefinition.metadata.isPositive) {
|
||||
if (!canBeCastAsPositiveIntegerOrNull(newText)) {
|
||||
return;
|
||||
}
|
||||
@ -64,7 +65,7 @@ export function GenericEditableNumberCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(numberValue.toString());
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, numberValue);
|
||||
updateField(currentRowEntityId, columnDefinition, numberValue);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldPhoneMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldPhoneMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { PhoneInputDisplay } from '@/ui/input/phone/components/PhoneInputDisplay';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditablePhoneCellEditMode } from './GenericEditablePhoneCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldPhoneMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldPhoneMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
export function GenericEditablePhoneCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
@ -25,7 +24,7 @@ export function GenericEditablePhoneCell({
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -34,7 +33,7 @@ export function GenericEditablePhoneCell({
|
||||
useEditButton
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditablePhoneCellEditMode viewField={viewField} />
|
||||
<GenericEditablePhoneCellEditMode columnDefinition={columnDefinition} />
|
||||
}
|
||||
nonEditModeContent={<PhoneInputDisplay value={fieldValue} />}
|
||||
></EditableCell>
|
||||
|
@ -1,27 +1,28 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldPhoneMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldPhoneMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { PhoneCellEdit } from './PhoneCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldPhoneMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldPhoneMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditablePhoneCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditablePhoneCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -33,13 +34,13 @@ export function GenericEditablePhoneCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(newText);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, newText);
|
||||
updateField(currentRowEntityId, columnDefinition, newText);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<PhoneCellEdit
|
||||
placeholder={viewField.metadata.placeHolder ?? ''}
|
||||
placeholder={columnDefinition.metadata.placeHolder ?? ''}
|
||||
autoFocus
|
||||
value={fieldValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
|
@ -1,21 +1,20 @@
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldRelationMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableRelationCellDisplayMode } from './GenericEditableRelationCellDisplayMode';
|
||||
import { GenericEditableRelationCellEditMode } from './GenericEditableRelationCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
fieldDefinition: ViewFieldDefinition<ViewFieldRelationMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldRelationMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCell({
|
||||
fieldDefinition,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
placeholder,
|
||||
}: OwnProps) {
|
||||
@ -25,11 +24,13 @@ export function GenericEditableRelationCell({
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editHotkeyScope={{ scope: RelationPickerHotkeyScope.RelationPicker }}
|
||||
editModeContent={
|
||||
<GenericEditableRelationCellEditMode viewField={fieldDefinition} />
|
||||
<GenericEditableRelationCellEditMode
|
||||
columnDefinition={columnDefinition}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={
|
||||
<GenericEditableRelationCellDisplayMode
|
||||
fieldDefinition={fieldDefinition}
|
||||
columnDefinition={columnDefinition}
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
|
@ -1,24 +1,23 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldRelationMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
import { UserChip } from '@/users/components/UserChip';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
type OwnProps = {
|
||||
fieldDefinition: ViewFieldDefinition<ViewFieldRelationMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldRelationMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCellDisplayMode({
|
||||
fieldDefinition,
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
@ -26,11 +25,11 @@ export function GenericEditableRelationCellDisplayMode({
|
||||
const fieldValue = useRecoilValue<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldDefinition.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
switch (fieldDefinition.metadata.relationType) {
|
||||
switch (columnDefinition.metadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyChip
|
||||
@ -51,7 +50,7 @@ export function GenericEditableRelationCellDisplayMode({
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${fieldDefinition.metadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
`Unknown relation type: "${columnDefinition.metadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
);
|
||||
return <> </>;
|
||||
}
|
||||
|
@ -4,10 +4,7 @@ import {
|
||||
CompanyPickerCell,
|
||||
CompanyPickerSelectedCompany,
|
||||
} from '@/companies/components/CompanyPickerCell';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldRelationMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||
import { useEditableCell } from '@/ui/table/editable-cell/hooks/useEditableCell';
|
||||
@ -16,11 +13,15 @@ import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
import { UserPicker } from '@/users/components/UserPicker';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldRelationMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldRelationMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableRelationCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const { closeEditableCell } = useEditableCell();
|
||||
@ -28,7 +29,7 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
||||
const [fieldValueEntity, setFieldValueEntity] = useRecoilState<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
const updateEntityField = useUpdateEntityField();
|
||||
@ -71,7 +72,7 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
||||
updateCachedCompanyField(newFieldEntity);
|
||||
updateEntityField<ViewFieldRelationMetadata, EntityForSelect>(
|
||||
currentRowEntityId,
|
||||
viewField,
|
||||
columnDefinition,
|
||||
newFieldEntity,
|
||||
);
|
||||
}
|
||||
@ -86,7 +87,7 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
||||
updateEntityField
|
||||
) {
|
||||
updateCachedPersonField(newFieldEntity);
|
||||
updateEntityField(currentRowEntityId, viewField, newFieldEntity);
|
||||
updateEntityField(currentRowEntityId, columnDefinition, newFieldEntity);
|
||||
}
|
||||
|
||||
closeEditableCell();
|
||||
@ -96,14 +97,14 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
||||
closeEditableCell();
|
||||
}
|
||||
|
||||
switch (viewField.metadata.relationType) {
|
||||
switch (columnDefinition.metadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyPickerCell
|
||||
companyId={fieldValueEntity?.id ?? null}
|
||||
onSubmit={handleCompanySubmit}
|
||||
onCancel={handleCancel}
|
||||
width={viewField.columnSize}
|
||||
width={columnDefinition.size}
|
||||
createModeEnabled
|
||||
/>
|
||||
);
|
||||
@ -114,13 +115,13 @@ export function GenericEditableRelationCellEditMode({ viewField }: OwnProps) {
|
||||
userId={fieldValueEntity?.id ?? null}
|
||||
onSubmit={handlePersonSubmit}
|
||||
onCancel={handleCancel}
|
||||
width={viewField.columnSize}
|
||||
width={columnDefinition.size}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${viewField.metadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
`Unknown relation type: "${columnDefinition.metadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
|
@ -1,23 +1,22 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldTextMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldTextMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { TextInputDisplay } from '@/ui/input/text/components/TextInputDisplay';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableTextCellEditMode } from './GenericEditableTextCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldTextMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldTextMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
export function GenericEditableTextCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
@ -25,7 +24,7 @@ export function GenericEditableTextCell({
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -33,7 +32,7 @@ export function GenericEditableTextCell({
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableTextCellEditMode viewField={viewField} />
|
||||
<GenericEditableTextCellEditMode columnDefinition={columnDefinition} />
|
||||
}
|
||||
nonEditModeContent={<TextInputDisplay>{fieldValue}</TextInputDisplay>}
|
||||
></EditableCell>
|
||||
|
@ -1,27 +1,28 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldTextMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldTextMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { TextCellEdit } from './TextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldTextMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldTextMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableTextCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableTextCellEditMode({
|
||||
columnDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -33,13 +34,13 @@ export function GenericEditableTextCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(newText);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, newText);
|
||||
updateField(currentRowEntityId, columnDefinition, newText);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<TextCellEdit
|
||||
placeholder={viewField.metadata.placeHolder ?? ''}
|
||||
placeholder={columnDefinition.metadata.placeHolder ?? ''}
|
||||
autoFocus
|
||||
value={fieldValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
|
@ -1,24 +1,23 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldURLMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldURLMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { InplaceInputURLDisplayMode } from '@/ui/input/url/components/URLTextInputDisplay';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
import { sanitizeURL } from '~/utils';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { GenericEditableURLCellEditMode } from './GenericEditableURLCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldURLMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldURLMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
};
|
||||
|
||||
export function GenericEditableURLCell({
|
||||
viewField,
|
||||
columnDefinition,
|
||||
editModeHorizontalAlign,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
@ -26,7 +25,7 @@ export function GenericEditableURLCell({
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -34,7 +33,9 @@ export function GenericEditableURLCell({
|
||||
<EditableCell
|
||||
useEditButton
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={<GenericEditableURLCellEditMode viewField={viewField} />}
|
||||
editModeContent={
|
||||
<GenericEditableURLCellEditMode columnDefinition={columnDefinition} />
|
||||
}
|
||||
nonEditModeContent={
|
||||
<InplaceInputURLDisplayMode value={sanitizeURL(fieldValue)} />
|
||||
}
|
||||
|
@ -1,28 +1,27 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldURLMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldURLMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
|
||||
import { isURL } from '~/utils/is-url';
|
||||
|
||||
import type { ColumnDefinition } from '../../../types/ColumnDefinition';
|
||||
|
||||
import { TextCellEdit } from './TextCellEdit';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldURLMetadata>;
|
||||
columnDefinition: ColumnDefinition<ViewFieldURLMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableURLCellEditMode({ viewField }: OwnProps) {
|
||||
export function GenericEditableURLCellEditMode({ columnDefinition }: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
fieldName: columnDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -36,13 +35,13 @@ export function GenericEditableURLCellEditMode({ viewField }: OwnProps) {
|
||||
setFieldValue(newText);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, viewField, newText);
|
||||
updateField(currentRowEntityId, columnDefinition, newText);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<TextCellEdit
|
||||
placeholder={viewField.metadata.placeHolder ?? ''}
|
||||
placeholder={columnDefinition.metadata.placeHolder ?? ''}
|
||||
autoFocus
|
||||
value={fieldValue ?? ''}
|
||||
onSubmit={handleSubmit}
|
||||
|
@ -3,6 +3,7 @@ import { useContext } from 'react';
|
||||
import { isViewFieldBoolean } from '@/ui/editable-field/types/guards/isViewFieldBoolean';
|
||||
import { isViewFieldBooleanValue } from '@/ui/editable-field/types/guards/isViewFieldBooleanValue';
|
||||
import { isViewFieldChip } from '@/ui/editable-field/types/guards/isViewFieldChip';
|
||||
import { isViewFieldChipValue } from '@/ui/editable-field/types/guards/isViewFieldChipValue';
|
||||
import { isViewFieldDate } from '@/ui/editable-field/types/guards/isViewFieldDate';
|
||||
import { isViewFieldDateValue } from '@/ui/editable-field/types/guards/isViewFieldDateValue';
|
||||
import { isViewFieldDoubleText } from '@/ui/editable-field/types/guards/isViewFieldDoubleText';
|
||||
@ -21,14 +22,11 @@ import { isViewFieldText } from '@/ui/editable-field/types/guards/isViewFieldTex
|
||||
import { isViewFieldTextValue } from '@/ui/editable-field/types/guards/isViewFieldTextValue';
|
||||
import { isViewFieldURL } from '@/ui/editable-field/types/guards/isViewFieldURL';
|
||||
import { isViewFieldURLValue } from '@/ui/editable-field/types/guards/isViewFieldURLValue';
|
||||
|
||||
import { isViewFieldChipValue } from '../../editable-field/types/guards/isViewFieldChipValue';
|
||||
import {
|
||||
import type {
|
||||
ViewFieldChipMetadata,
|
||||
ViewFieldChipValue,
|
||||
ViewFieldDateMetadata,
|
||||
ViewFieldDateValue,
|
||||
ViewFieldDefinition,
|
||||
ViewFieldDoubleTextChipMetadata,
|
||||
ViewFieldDoubleTextChipValue,
|
||||
ViewFieldDoubleTextMetadata,
|
||||
@ -44,8 +42,10 @@ import {
|
||||
ViewFieldTextValue,
|
||||
ViewFieldURLMetadata,
|
||||
ViewFieldURLValue,
|
||||
} from '../../editable-field/types/ViewField';
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
export function useUpdateEntityField() {
|
||||
const updateEntity = useContext(EntityUpdateMutationContext);
|
||||
@ -73,7 +73,7 @@ export function useUpdateEntityField() {
|
||||
: unknown,
|
||||
>(
|
||||
currentEntityId: string,
|
||||
viewField: ViewFieldDefinition<MetadataType>,
|
||||
columnDefinition: ColumnDefinition<MetadataType>,
|
||||
newFieldValue: ValueType,
|
||||
) {
|
||||
const newFieldValueUnknown = newFieldValue as unknown;
|
||||
@ -85,12 +85,12 @@ export function useUpdateEntityField() {
|
||||
|
||||
// Relation
|
||||
if (
|
||||
isViewFieldRelation(viewField) &&
|
||||
isViewFieldRelation(columnDefinition) &&
|
||||
isViewFieldRelationValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newSelectedEntity = newFieldValueUnknown;
|
||||
|
||||
const fieldName = viewField.metadata.fieldName;
|
||||
const fieldName = columnDefinition.metadata.fieldName;
|
||||
if (!newSelectedEntity || newSelectedEntity.id === '') {
|
||||
updateEntity({
|
||||
variables: {
|
||||
@ -116,7 +116,7 @@ export function useUpdateEntityField() {
|
||||
}
|
||||
// Chip
|
||||
} else if (
|
||||
isViewFieldChip(viewField) &&
|
||||
isViewFieldChip(columnDefinition) &&
|
||||
isViewFieldChipValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -124,12 +124,12 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.contentFieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.contentFieldName]: newContent },
|
||||
},
|
||||
});
|
||||
// Text
|
||||
} else if (
|
||||
isViewFieldText(viewField) &&
|
||||
isViewFieldText(columnDefinition) &&
|
||||
isViewFieldTextValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -137,12 +137,12 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.fieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.fieldName]: newContent },
|
||||
},
|
||||
});
|
||||
// Double text
|
||||
} else if (
|
||||
isViewFieldDoubleText(viewField) &&
|
||||
isViewFieldDoubleText(columnDefinition) &&
|
||||
isViewFieldDoubleTextValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -151,14 +151,16 @@ export function useUpdateEntityField() {
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: {
|
||||
[viewField.metadata.firstValueFieldName]: newContent.firstValue,
|
||||
[viewField.metadata.secondValueFieldName]: newContent.secondValue,
|
||||
[columnDefinition.metadata.firstValueFieldName]:
|
||||
newContent.firstValue,
|
||||
[columnDefinition.metadata.secondValueFieldName]:
|
||||
newContent.secondValue,
|
||||
},
|
||||
},
|
||||
});
|
||||
// Double Text Chip
|
||||
} else if (
|
||||
isViewFieldDoubleTextChip(viewField) &&
|
||||
isViewFieldDoubleTextChip(columnDefinition) &&
|
||||
isViewFieldDoubleTextChipValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -167,14 +169,16 @@ export function useUpdateEntityField() {
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: {
|
||||
[viewField.metadata.firstValueFieldName]: newContent.firstValue,
|
||||
[viewField.metadata.secondValueFieldName]: newContent.secondValue,
|
||||
[columnDefinition.metadata.firstValueFieldName]:
|
||||
newContent.firstValue,
|
||||
[columnDefinition.metadata.secondValueFieldName]:
|
||||
newContent.secondValue,
|
||||
},
|
||||
},
|
||||
});
|
||||
// Phone
|
||||
} else if (
|
||||
isViewFieldPhone(viewField) &&
|
||||
isViewFieldPhone(columnDefinition) &&
|
||||
isViewFieldPhoneValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -182,12 +186,12 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.fieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.fieldName]: newContent },
|
||||
},
|
||||
});
|
||||
// URL
|
||||
} else if (
|
||||
isViewFieldURL(viewField) &&
|
||||
isViewFieldURL(columnDefinition) &&
|
||||
isViewFieldURLValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -195,12 +199,12 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.fieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.fieldName]: newContent },
|
||||
},
|
||||
});
|
||||
// Number
|
||||
} else if (
|
||||
isViewFieldNumber(viewField) &&
|
||||
isViewFieldNumber(columnDefinition) &&
|
||||
isViewFieldNumberValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -208,12 +212,12 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.fieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.fieldName]: newContent },
|
||||
},
|
||||
});
|
||||
// Boolean
|
||||
} else if (
|
||||
isViewFieldBoolean(viewField) &&
|
||||
isViewFieldBoolean(columnDefinition) &&
|
||||
isViewFieldBooleanValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -221,12 +225,12 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.fieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.fieldName]: newContent },
|
||||
},
|
||||
});
|
||||
// Money
|
||||
} else if (
|
||||
isViewFieldMoney(viewField) &&
|
||||
isViewFieldMoney(columnDefinition) &&
|
||||
isViewFieldMoneyValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -234,12 +238,12 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.fieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.fieldName]: newContent },
|
||||
},
|
||||
});
|
||||
// Date
|
||||
} else if (
|
||||
isViewFieldDate(viewField) &&
|
||||
isViewFieldDate(columnDefinition) &&
|
||||
isViewFieldDateValue(newFieldValueUnknown)
|
||||
) {
|
||||
const newContent = newFieldValueUnknown;
|
||||
@ -247,7 +251,7 @@ export function useUpdateEntityField() {
|
||||
updateEntity({
|
||||
variables: {
|
||||
where: { id: currentEntityId },
|
||||
data: { [viewField.metadata.fieldName]: newContent },
|
||||
data: { [columnDefinition.metadata.fieldName]: newContent },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -12,10 +12,7 @@ import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu'
|
||||
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
|
||||
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
|
||||
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState';
|
||||
import { savedFiltersScopedState } from '@/ui/filter-n-sort/states/savedFiltersScopedState';
|
||||
import { savedSortsScopedState } from '@/ui/filter-n-sort/states/savedSortsScopedState';
|
||||
@ -44,6 +41,7 @@ import {
|
||||
tableViewsByIdState,
|
||||
tableViewsState,
|
||||
} from '../../states/tableViewsState';
|
||||
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
|
||||
|
||||
import { TableOptionsDropdownSection } from './TableOptionsDropdownSection';
|
||||
@ -107,7 +105,7 @@ export function TableOptionsDropdownContent({
|
||||
);
|
||||
|
||||
const renderFieldActions = useCallback(
|
||||
(column: ViewFieldDefinition<ViewFieldMetadata>) =>
|
||||
(column: ColumnDefinition<ViewFieldMetadata>) =>
|
||||
// Do not allow hiding last visible column
|
||||
!column.isVisible || visibleColumns.length > 1
|
||||
? [
|
||||
|
@ -7,17 +7,16 @@ import {
|
||||
} from '@/ui/dropdown/components/DropdownMenuItem';
|
||||
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
|
||||
import { StyledDropdownMenuSubheader } from '@/ui/dropdown/components/StyledDropdownMenuSubheader';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
|
||||
type TableOptionsDropdownSectionProps = {
|
||||
renderActions: (
|
||||
column: ViewFieldDefinition<ViewFieldMetadata>,
|
||||
column: ColumnDefinition<ViewFieldMetadata>,
|
||||
) => DropdownMenuItemProps['actions'];
|
||||
title: string;
|
||||
columns: ViewFieldDefinition<ViewFieldMetadata>[];
|
||||
columns: ColumnDefinition<ViewFieldMetadata>[];
|
||||
};
|
||||
|
||||
export function TableOptionsDropdownSection({
|
||||
@ -33,11 +32,11 @@ export function TableOptionsDropdownSection({
|
||||
<StyledDropdownMenuItemsContainer>
|
||||
{columns.map((column) => (
|
||||
<DropdownMenuItem key={column.id} actions={renderActions(column)}>
|
||||
{column.columnIcon &&
|
||||
cloneElement(column.columnIcon, {
|
||||
{column.icon &&
|
||||
cloneElement(column.icon, {
|
||||
size: theme.icon.size.md,
|
||||
})}
|
||||
{column.columnLabel}
|
||||
{column.label}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</StyledDropdownMenuItemsContainer>
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { atomFamily } from 'recoil';
|
||||
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
export const savedTableColumnsScopedState = atomFamily<
|
||||
ViewFieldDefinition<ViewFieldMetadata>[],
|
||||
ColumnDefinition<ViewFieldMetadata>[],
|
||||
string | undefined
|
||||
>({
|
||||
key: 'savedTableColumnsScopedState',
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
import { savedTableColumnsScopedState } from '../savedTableColumnsScopedState';
|
||||
|
||||
export const savedTableColumnsByIdScopedSelector = selectorFamily({
|
||||
@ -13,6 +11,6 @@ export const savedTableColumnsByIdScopedSelector = selectorFamily({
|
||||
(viewId: string | undefined) =>
|
||||
({ get }) =>
|
||||
get(savedTableColumnsScopedState(viewId)).reduce<
|
||||
Record<string, ViewFieldDefinition<ViewFieldMetadata>>
|
||||
Record<string, ColumnDefinition<ViewFieldMetadata>>
|
||||
>((result, column) => ({ ...result, [column.id]: column }), {}),
|
||||
});
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { selectorFamily } from 'recoil';
|
||||
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../../types/ColumnDefinition';
|
||||
import { tableColumnsScopedState } from '../tableColumnsScopedState';
|
||||
|
||||
export const tableColumnsByIdScopedSelector = selectorFamily({
|
||||
@ -13,6 +11,6 @@ export const tableColumnsByIdScopedSelector = selectorFamily({
|
||||
(scopeId: string) =>
|
||||
({ get }) =>
|
||||
get(tableColumnsScopedState(scopeId)).reduce<
|
||||
Record<string, ViewFieldDefinition<ViewFieldMetadata>>
|
||||
Record<string, ColumnDefinition<ViewFieldMetadata>>
|
||||
>((result, column) => ({ ...result, [column.id]: column }), {}),
|
||||
});
|
||||
|
@ -1,12 +1,11 @@
|
||||
import { atomFamily } from 'recoil';
|
||||
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
import type { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
export const tableColumnsScopedState = atomFamily<
|
||||
ViewFieldDefinition<ViewFieldMetadata>[],
|
||||
ColumnDefinition<ViewFieldMetadata>[],
|
||||
string
|
||||
>({
|
||||
key: 'tableColumnsScopedState',
|
||||
|
10
front/src/modules/ui/table/types/ColumnDefinition.ts
Normal file
10
front/src/modules/ui/table/types/ColumnDefinition.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
|
||||
export type ColumnDefinition<T extends ViewFieldMetadata | unknown> =
|
||||
ViewFieldDefinition<T> & {
|
||||
size: number;
|
||||
order: number;
|
||||
};
|
@ -2,7 +2,6 @@ import { useCallback } from 'react';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
ViewFieldTextMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
@ -11,6 +10,7 @@ import { savedTableColumnsScopedState } from '@/ui/table/states/savedTableColumn
|
||||
import { savedTableColumnsByIdScopedSelector } from '@/ui/table/states/selectors/savedTableColumnsByIdScopedSelector';
|
||||
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
|
||||
import { currentTableViewIdState } from '@/ui/table/states/tableViewsState';
|
||||
import type { ColumnDefinition } from '@/ui/table/types/ColumnDefinition';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import {
|
||||
@ -29,21 +29,21 @@ const DEFAULT_VIEW_FIELD_METADATA: ViewFieldTextMetadata = {
|
||||
|
||||
const toViewFieldInput = (
|
||||
objectName: 'company' | 'person',
|
||||
viewFieldDefinition: ViewFieldDefinition<ViewFieldMetadata>,
|
||||
fieldDefinition: ColumnDefinition<ViewFieldMetadata>,
|
||||
) => ({
|
||||
fieldName: viewFieldDefinition.columnLabel,
|
||||
index: viewFieldDefinition.columnOrder,
|
||||
isVisible: viewFieldDefinition.isVisible ?? true,
|
||||
fieldName: fieldDefinition.label,
|
||||
index: fieldDefinition.order,
|
||||
isVisible: fieldDefinition.isVisible ?? true,
|
||||
objectName,
|
||||
sizeInPx: viewFieldDefinition.columnSize,
|
||||
sizeInPx: fieldDefinition.size,
|
||||
});
|
||||
|
||||
export const useTableViewFields = ({
|
||||
objectName,
|
||||
viewFieldDefinitions,
|
||||
columnDefinitions,
|
||||
}: {
|
||||
objectName: 'company' | 'person';
|
||||
viewFieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[];
|
||||
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
|
||||
}) => {
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
currentTableViewIdState,
|
||||
@ -65,7 +65,7 @@ export const useTableViewFields = ({
|
||||
|
||||
const createViewFields = useCallback(
|
||||
(
|
||||
columns: ViewFieldDefinition<ViewFieldMetadata>[],
|
||||
columns: ColumnDefinition<ViewFieldMetadata>[],
|
||||
viewId = currentViewId,
|
||||
) => {
|
||||
if (!viewId || !columns.length) return;
|
||||
@ -83,7 +83,7 @@ export const useTableViewFields = ({
|
||||
);
|
||||
|
||||
const updateViewFields = useCallback(
|
||||
(columns: ViewFieldDefinition<ViewFieldMetadata>[]) => {
|
||||
(columns: ColumnDefinition<ViewFieldMetadata>[]) => {
|
||||
if (!currentViewId || !columns.length) return;
|
||||
|
||||
return Promise.all(
|
||||
@ -92,7 +92,7 @@ export const useTableViewFields = ({
|
||||
variables: {
|
||||
data: {
|
||||
isVisible: column.isVisible,
|
||||
sizeInPx: column.columnSize,
|
||||
sizeInPx: column.size,
|
||||
},
|
||||
where: { id: column.id },
|
||||
},
|
||||
@ -115,20 +115,20 @@ export const useTableViewFields = ({
|
||||
onCompleted: async (data) => {
|
||||
if (!data.viewFields.length) {
|
||||
// Populate if empty
|
||||
await createViewFields(viewFieldDefinitions);
|
||||
await createViewFields(columnDefinitions);
|
||||
return refetch();
|
||||
}
|
||||
|
||||
const nextColumns = data.viewFields.map<
|
||||
ViewFieldDefinition<ViewFieldMetadata>
|
||||
ColumnDefinition<ViewFieldMetadata>
|
||||
>((viewField) => ({
|
||||
...(viewFieldDefinitions.find(
|
||||
({ columnLabel }) => viewField.fieldName === columnLabel,
|
||||
...(columnDefinitions.find(
|
||||
({ label: columnLabel }) => viewField.fieldName === columnLabel,
|
||||
) || { metadata: DEFAULT_VIEW_FIELD_METADATA }),
|
||||
id: viewField.id,
|
||||
columnLabel: viewField.fieldName,
|
||||
columnOrder: viewField.index,
|
||||
columnSize: viewField.sizeInPx,
|
||||
label: viewField.fieldName,
|
||||
order: viewField.index,
|
||||
size: viewField.sizeInPx,
|
||||
isVisible: viewField.isVisible,
|
||||
}));
|
||||
|
||||
@ -145,7 +145,7 @@ export const useTableViewFields = ({
|
||||
const viewFieldsToUpdate = columns.filter(
|
||||
(column) =>
|
||||
savedColumnsById[column.id] &&
|
||||
(savedColumnsById[column.id].columnSize !== column.columnSize ||
|
||||
(savedColumnsById[column.id].size !== column.size ||
|
||||
savedColumnsById[column.id].isVisible !== column.isVisible),
|
||||
);
|
||||
await updateViewFields(viewFieldsToUpdate);
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import type {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import type { ViewFieldMetadata } from '@/ui/editable-field/types/ViewField';
|
||||
import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState';
|
||||
import { sortsScopedState } from '@/ui/filter-n-sort/states/sortsScopedState';
|
||||
import type { FilterDefinitionByEntity } from '@/ui/filter-n-sort/types/FilterDefinitionByEntity';
|
||||
@ -11,6 +8,7 @@ import type { SortType } from '@/ui/filter-n-sort/types/interface';
|
||||
import { TableRecoilScopeContext } from '@/ui/table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { tableColumnsScopedState } from '@/ui/table/states/tableColumnsScopedState';
|
||||
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 { useTableViewFields } from './useTableViewFields';
|
||||
@ -22,12 +20,12 @@ export const useTableViews = <Entity, SortField>({
|
||||
availableFilters,
|
||||
availableSorts,
|
||||
objectId,
|
||||
viewFieldDefinitions,
|
||||
columnDefinitions,
|
||||
}: {
|
||||
availableFilters: FilterDefinitionByEntity<Entity>[];
|
||||
availableSorts: SortType<SortField>[];
|
||||
objectId: 'company' | 'person';
|
||||
viewFieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[];
|
||||
columnDefinitions: ColumnDefinition<ViewFieldMetadata>[];
|
||||
}) => {
|
||||
const currentViewId = useRecoilScopedValue(
|
||||
currentTableViewIdState,
|
||||
@ -48,7 +46,7 @@ export const useTableViews = <Entity, SortField>({
|
||||
|
||||
const { createViewFields, persistColumns } = useTableViewFields({
|
||||
objectName: objectId,
|
||||
viewFieldDefinitions,
|
||||
columnDefinitions,
|
||||
});
|
||||
const { createViewFilters, persistFilters } = useViewFilters({
|
||||
availableFilters,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { companyViewFields } from '@/companies/constants/companyViewFields';
|
||||
import { companiesAvailableColumnDefinitions } from '@/companies/constants/companiesAvailableColumnDefinitions';
|
||||
import { Company, User, ViewField } from '~/generated/graphql';
|
||||
|
||||
type MockedCompany = Pick<
|
||||
@ -144,14 +144,13 @@ export const mockedCompaniesData: Array<MockedCompany> = [
|
||||
},
|
||||
];
|
||||
|
||||
export const mockedCompanyViewFields = companyViewFields.map<ViewField>(
|
||||
(viewFieldDefinition) => ({
|
||||
export const mockedCompanyViewFields =
|
||||
companiesAvailableColumnDefinitions.map<ViewField>((viewFieldDefinition) => ({
|
||||
__typename: 'ViewField',
|
||||
fieldName: viewFieldDefinition.columnLabel,
|
||||
fieldName: viewFieldDefinition.label,
|
||||
id: viewFieldDefinition.id,
|
||||
index: viewFieldDefinition.columnOrder,
|
||||
index: viewFieldDefinition.order,
|
||||
isVisible: true,
|
||||
objectName: 'company',
|
||||
sizeInPx: viewFieldDefinition.columnSize,
|
||||
}),
|
||||
);
|
||||
sizeInPx: viewFieldDefinition.size,
|
||||
}));
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { peopleViewFields } from '@/people/constants/peopleViewFields';
|
||||
import { peopleAvailableColumnDefinitions } from '@/people/constants/peopleAvailableColumnDefinitions';
|
||||
import { Company, Person, ViewField } from '~/generated/graphql';
|
||||
|
||||
type RequiredAndNotNull<T> = {
|
||||
@ -123,14 +123,13 @@ export const mockedPeopleData: MockedPerson[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const mockedPersonViewFields = peopleViewFields.map<ViewField>(
|
||||
(viewFieldDefinition) => ({
|
||||
export const mockedPersonViewFields =
|
||||
peopleAvailableColumnDefinitions.map<ViewField>((viewFieldDefinition) => ({
|
||||
__typename: 'ViewField',
|
||||
fieldName: viewFieldDefinition.columnLabel,
|
||||
fieldName: viewFieldDefinition.label,
|
||||
id: viewFieldDefinition.id,
|
||||
index: viewFieldDefinition.columnOrder,
|
||||
index: viewFieldDefinition.order,
|
||||
isVisible: true,
|
||||
objectName: 'person',
|
||||
sizeInPx: viewFieldDefinition.columnSize,
|
||||
}),
|
||||
);
|
||||
sizeInPx: viewFieldDefinition.size,
|
||||
}));
|
||||
|
Loading…
Reference in New Issue
Block a user