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:
Thaïs 2023-08-28 18:33:03 +02:00 committed by GitHub
parent 0d7b869274
commit 74919eff7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 770 additions and 772 deletions

View File

@ -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,
}}

View File

@ -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);

View File

@ -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>,
];

View File

@ -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>,
];

View File

@ -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();

View File

@ -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 <></>;

View File

@ -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>,
];

View File

@ -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>,
];

View File

@ -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();

View File

@ -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>,
];

View File

@ -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>,
];

View File

@ -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;
};

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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>

View 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);

View File

@ -1,9 +0,0 @@
import { createContext } from 'react';
import {
ViewFieldDefinition,
ViewFieldMetadata,
} from '../../editable-field/types/ViewField';
export const ViewFieldContext =
createContext<ViewFieldDefinition<ViewFieldMetadata> | null>(null);

View File

@ -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 <></>;
}

View File

@ -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(

View File

@ -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>
);

View File

@ -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 <> </>;
}

View File

@ -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}

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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}

View File

@ -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>
);

View File

@ -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 <> </>;
}

View File

@ -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}

View File

@ -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>

View File

@ -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}

View File

@ -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)}` : ''}</>

View File

@ -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(

View File

@ -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>

View File

@ -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(

View File

@ -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>

View File

@ -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}

View File

@ -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}
/>

View File

@ -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 <> </>;
}

View File

@ -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 <></>;
}

View File

@ -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>

View File

@ -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}

View File

@ -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)} />
}

View File

@ -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}

View File

@ -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 },
},
});
}

View File

@ -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
? [

View File

@ -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>

View File

@ -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',

View File

@ -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 }), {}),
});

View File

@ -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 }), {}),
});

View File

@ -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',

View 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;
};

View File

@ -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);

View File

@ -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,

View File

@ -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,
}));

View File

@ -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,
}));