Feat/generic editable cell chip (#982)
* Added generic relation cell * Deactivated debug * Added default warning * Put back display component * Removed unused types * wip * Renamed to view field * Use new view field structure to have chip working * Finished * Added a temp feature flag
This commit is contained in:
@ -7,7 +7,7 @@ import { RecoilScope } from '../../recoil-scope/components/RecoilScope';
|
||||
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
|
||||
import { ColumnIndexContext } from '../states/ColumnIndexContext';
|
||||
import { contextMenuPositionState } from '../states/contextMenuPositionState';
|
||||
import { EntityFieldMetadataContext } from '../states/EntityFieldMetadataContext';
|
||||
import { ViewFieldContext } from '../states/ViewFieldContext';
|
||||
|
||||
export function EntityTableCell({ cellIndex }: { cellIndex: number }) {
|
||||
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
|
||||
@ -25,7 +25,7 @@ export function EntityTableCell({ cellIndex }: { cellIndex: number }) {
|
||||
});
|
||||
}
|
||||
|
||||
const entityFieldMetadata = useContext(EntityFieldMetadataContext);
|
||||
const entityFieldMetadata = useContext(ViewFieldContext);
|
||||
|
||||
if (!entityFieldMetadata) {
|
||||
return null;
|
||||
@ -42,7 +42,7 @@ export function EntityTableCell({ cellIndex }: { cellIndex: number }) {
|
||||
maxWidth: entityFieldMetadata.columnSize,
|
||||
}}
|
||||
>
|
||||
<GenericEditableCell entityFieldMetadata={entityFieldMetadata} />
|
||||
<GenericEditableCell fieldDefinition={entityFieldMetadata} />
|
||||
</td>
|
||||
</ColumnIndexContext.Provider>
|
||||
</RecoilScope>
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { entityFieldMetadataArrayState } from '../states/entityFieldMetadataArrayState';
|
||||
import { viewFieldsState } from '../states/viewFieldsState';
|
||||
|
||||
import { ColumnHead } from './ColumnHead';
|
||||
import { SelectAllCheckbox } from './SelectAllCheckbox';
|
||||
|
||||
export function EntityTableHeader() {
|
||||
const fieldMetadataArray = useRecoilValue(entityFieldMetadataArrayState);
|
||||
const viewFields = useRecoilValue(viewFieldsState);
|
||||
|
||||
return (
|
||||
<thead>
|
||||
@ -20,18 +20,18 @@ export function EntityTableHeader() {
|
||||
>
|
||||
<SelectAllCheckbox />
|
||||
</th>
|
||||
{fieldMetadataArray.map((fieldMetadata) => (
|
||||
{viewFields.map((viewField) => (
|
||||
<th
|
||||
key={fieldMetadata.fieldName.toString()}
|
||||
key={viewField.columnOrder.toString()}
|
||||
style={{
|
||||
width: fieldMetadata.columnSize,
|
||||
minWidth: fieldMetadata.columnSize,
|
||||
maxWidth: fieldMetadata.columnSize,
|
||||
width: viewField.columnSize,
|
||||
minWidth: viewField.columnSize,
|
||||
maxWidth: viewField.columnSize,
|
||||
}}
|
||||
>
|
||||
<ColumnHead
|
||||
viewName={fieldMetadata.label}
|
||||
viewIcon={fieldMetadata.icon}
|
||||
viewName={viewField.columnLabel}
|
||||
viewIcon={viewField.columnIcon}
|
||||
/>
|
||||
</th>
|
||||
))}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { entityFieldMetadataArrayState } from '../states/entityFieldMetadataArrayState';
|
||||
import { EntityFieldMetadataContext } from '../states/EntityFieldMetadataContext';
|
||||
import { ViewFieldContext } from '../states/ViewFieldContext';
|
||||
import { viewFieldsState } from '../states/viewFieldsState';
|
||||
|
||||
import { CheckboxCell } from './CheckboxCell';
|
||||
import { EntityTableCell } from './EntityTableCellV2';
|
||||
@ -13,9 +13,7 @@ const StyledRow = styled.tr<{ selected: boolean }>`
|
||||
`;
|
||||
|
||||
export function EntityTableRow({ rowId }: { rowId: string }) {
|
||||
const entityFieldMetadataArray = useRecoilValue(
|
||||
entityFieldMetadataArrayState,
|
||||
);
|
||||
const entityFieldMetadataArray = useRecoilValue(viewFieldsState);
|
||||
|
||||
return (
|
||||
<StyledRow data-testid={`row-id-${rowId}`} selected={false}>
|
||||
@ -24,12 +22,12 @@ export function EntityTableRow({ rowId }: { rowId: string }) {
|
||||
</td>
|
||||
{entityFieldMetadataArray.map((entityFieldMetadata, columnIndex) => {
|
||||
return (
|
||||
<EntityFieldMetadataContext.Provider
|
||||
<ViewFieldContext.Provider
|
||||
value={entityFieldMetadata}
|
||||
key={entityFieldMetadata.fieldName}
|
||||
key={entityFieldMetadata.columnOrder}
|
||||
>
|
||||
<EntityTableCell cellIndex={columnIndex} />
|
||||
</EntityFieldMetadataContext.Provider>
|
||||
</ViewFieldContext.Provider>
|
||||
);
|
||||
})}
|
||||
<td></td>
|
||||
|
||||
@ -1,31 +1,38 @@
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
import { ViewFieldDefinition } from '@/ui/table/types/ViewField';
|
||||
|
||||
import { isViewFieldChip } from '../types/guards/isViewFieldChip';
|
||||
import { isViewFieldRelation } from '../types/guards/isViewFieldRelation';
|
||||
import { isViewFieldText } from '../types/guards/isViewFieldText';
|
||||
|
||||
import { GenericEditableChipCell } from './GenericEditableChipCell';
|
||||
import { GenericEditableRelationCell } from './GenericEditableRelationCell';
|
||||
import { GenericEditableTextCell } from './GenericEditableTextCell';
|
||||
|
||||
type OwnProps = {
|
||||
entityFieldMetadata: EntityFieldMetadata;
|
||||
fieldDefinition: ViewFieldDefinition<unknown>;
|
||||
};
|
||||
|
||||
export function GenericEditableCell({ entityFieldMetadata }: OwnProps) {
|
||||
switch (entityFieldMetadata.type) {
|
||||
case 'text':
|
||||
return (
|
||||
<GenericEditableTextCell
|
||||
fieldName={entityFieldMetadata.fieldName}
|
||||
placeholder={entityFieldMetadata.label}
|
||||
editModeHorizontalAlign="left"
|
||||
/>
|
||||
);
|
||||
case 'relation': {
|
||||
return (
|
||||
<GenericEditableRelationCell fieldMetadata={entityFieldMetadata} />
|
||||
);
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown field type: ${entityFieldMetadata.type} in GenericEditableCell`,
|
||||
);
|
||||
return <></>;
|
||||
export function GenericEditableCell({ fieldDefinition }: OwnProps) {
|
||||
if (isViewFieldText(fieldDefinition)) {
|
||||
return (
|
||||
<GenericEditableTextCell
|
||||
viewField={fieldDefinition}
|
||||
editModeHorizontalAlign="left"
|
||||
/>
|
||||
);
|
||||
} else if (isViewFieldRelation(fieldDefinition)) {
|
||||
return <GenericEditableRelationCell fieldDefinition={fieldDefinition} />;
|
||||
} else if (isViewFieldChip(fieldDefinition)) {
|
||||
return (
|
||||
<GenericEditableChipCell
|
||||
viewField={fieldDefinition}
|
||||
editModeHorizontalAlign="left"
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
console.warn(
|
||||
`Unknown field type: ${fieldDefinition.type} in GenericEditableCell`,
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
|
||||
import { ViewFieldChipMetadata, ViewFieldDefinition } from '../types/ViewField';
|
||||
|
||||
import { GenericEditableChipCellDisplayMode } from './GenericEditableChipCellDisplayMode';
|
||||
import { GenericEditableTextCellEditMode } from './GenericEditableTextCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldChipMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableChipCell({
|
||||
viewField,
|
||||
editModeHorizontalAlign,
|
||||
placeholder,
|
||||
}: OwnProps) {
|
||||
return (
|
||||
<EditableCell
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableTextCellEditMode
|
||||
fieldName={viewField.metadata.contentFieldName}
|
||||
viewFieldId={viewField.id}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={
|
||||
<GenericEditableChipCellDisplayMode fieldDefinition={viewField} />
|
||||
}
|
||||
></EditableCell>
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
import {
|
||||
ViewFieldChipMetadata,
|
||||
ViewFieldDefinition,
|
||||
} from '@/ui/table/types/ViewField';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
|
||||
type OwnProps = {
|
||||
fieldDefinition: ViewFieldDefinition<ViewFieldChipMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableChipCellDisplayMode({
|
||||
fieldDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const content = useRecoilValue<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldDefinition.metadata.contentFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
const chipUrl = useRecoilValue<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldDefinition.metadata.urlFieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
switch (fieldDefinition.metadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyChip
|
||||
id={currentRowEntityId ?? ''}
|
||||
name={content ?? ''}
|
||||
pictureUrl={getLogoUrlFromDomainName(chipUrl)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${fieldDefinition.metadata.relationType}" in GenericEditableChipCellEditMode`,
|
||||
);
|
||||
return <> </>;
|
||||
}
|
||||
}
|
||||
@ -1,18 +1,21 @@
|
||||
import { RelationPickerHotkeyScope } from '@/ui/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/table/types/ViewField';
|
||||
|
||||
import { GenericEditableRelationCellDisplayMode } from './GenericEditableRelationCellDisplayMode';
|
||||
import { GenericEditableRelationCellEditMode } from './GenericEditableRelationCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
fieldMetadata: EntityFieldMetadata;
|
||||
fieldDefinition: ViewFieldDefinition<ViewFieldRelationMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCell({
|
||||
fieldMetadata,
|
||||
fieldDefinition,
|
||||
editModeHorizontalAlign,
|
||||
placeholder,
|
||||
}: OwnProps) {
|
||||
@ -21,11 +24,13 @@ export function GenericEditableRelationCell({
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editHotkeyScope={{ scope: RelationPickerHotkeyScope.RelationPicker }}
|
||||
editModeContent={
|
||||
<GenericEditableRelationCellEditMode fieldMetadata={fieldMetadata} />
|
||||
<GenericEditableRelationCellEditMode
|
||||
viewFieldDefinition={fieldDefinition}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={
|
||||
<GenericEditableRelationCellDisplayMode
|
||||
fieldMetadata={fieldMetadata}
|
||||
fieldDefinition={fieldDefinition}
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
|
||||
@ -4,28 +4,31 @@ import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/table/types/ViewField';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
|
||||
type OwnProps = {
|
||||
fieldMetadata: EntityFieldMetadata;
|
||||
fieldDefinition: ViewFieldDefinition<ViewFieldRelationMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCellDisplayMode({
|
||||
fieldMetadata,
|
||||
fieldDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
const fieldValue = useRecoilValue<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldMetadata.fieldName,
|
||||
fieldName: fieldDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
switch (fieldMetadata.relationType) {
|
||||
switch (fieldDefinition.metadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyChip
|
||||
@ -37,7 +40,7 @@ export function GenericEditableRelationCellDisplayMode({
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${fieldMetadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
`Unknown relation type: "${fieldDefinition.metadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
);
|
||||
return <> </>;
|
||||
}
|
||||
|
||||
@ -7,14 +7,17 @@ import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
|
||||
import { useEditableCell } from '@/ui/table/editable-cell/hooks/useEditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
import { EntityFieldMetadata } from '@/ui/table/types/EntityFieldMetadata';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldRelationMetadata,
|
||||
} from '@/ui/table/types/ViewField';
|
||||
|
||||
type OwnProps = {
|
||||
fieldMetadata: EntityFieldMetadata;
|
||||
viewFieldDefinition: ViewFieldDefinition<ViewFieldRelationMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableRelationCellEditMode({
|
||||
fieldMetadata,
|
||||
viewFieldDefinition,
|
||||
}: OwnProps) {
|
||||
const currentRowEntityId = useCurrentRowEntityId();
|
||||
|
||||
@ -23,7 +26,7 @@ export function GenericEditableRelationCellEditMode({
|
||||
const [fieldValueEntity] = useRecoilState<any | null>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName: fieldMetadata.fieldName,
|
||||
fieldName: viewFieldDefinition.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -37,7 +40,7 @@ export function GenericEditableRelationCellEditMode({
|
||||
) {
|
||||
updateEntityField(
|
||||
currentRowEntityId,
|
||||
fieldMetadata.fieldName,
|
||||
viewFieldDefinition.id,
|
||||
newFieldEntity,
|
||||
);
|
||||
}
|
||||
@ -49,7 +52,7 @@ export function GenericEditableRelationCellEditMode({
|
||||
closeEditableCell();
|
||||
}
|
||||
|
||||
switch (fieldMetadata.relationType) {
|
||||
switch (viewFieldDefinition.metadata.relationType) {
|
||||
case Entity.Company: {
|
||||
return (
|
||||
<CompanyPickerCell
|
||||
@ -61,7 +64,7 @@ export function GenericEditableRelationCellEditMode({
|
||||
}
|
||||
default:
|
||||
console.warn(
|
||||
`Unknown relation type: "${fieldMetadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
`Unknown relation type: "${viewFieldDefinition.metadata.relationType}" in GenericEditableRelationCellEditMode`,
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
|
||||
@ -5,16 +5,18 @@ import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
|
||||
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
|
||||
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
|
||||
|
||||
import { ViewFieldDefinition, ViewFieldTextMetadata } from '../types/ViewField';
|
||||
|
||||
import { GenericEditableTextCellEditMode } from './GenericEditableTextCellEditMode';
|
||||
|
||||
type OwnProps = {
|
||||
fieldName: string;
|
||||
viewField: ViewFieldDefinition<ViewFieldTextMetadata>;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableTextCell({
|
||||
fieldName,
|
||||
viewField,
|
||||
editModeHorizontalAlign,
|
||||
placeholder,
|
||||
}: OwnProps) {
|
||||
@ -23,7 +25,7 @@ export function GenericEditableTextCell({
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
tableEntityFieldFamilySelector({
|
||||
entityId: currentRowEntityId ?? '',
|
||||
fieldName,
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
|
||||
@ -32,7 +34,8 @@ export function GenericEditableTextCell({
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeContent={
|
||||
<GenericEditableTextCellEditMode
|
||||
fieldName={fieldName}
|
||||
fieldName={viewField.metadata.fieldName}
|
||||
viewFieldId={viewField.id}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
}
|
||||
|
||||
@ -7,15 +7,18 @@ import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFie
|
||||
|
||||
type OwnProps = {
|
||||
fieldName: string;
|
||||
viewFieldId: string;
|
||||
placeholder?: string;
|
||||
};
|
||||
|
||||
export function GenericEditableTextCellEditMode({
|
||||
fieldName,
|
||||
viewFieldId,
|
||||
placeholder,
|
||||
}: 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 ?? '',
|
||||
@ -31,7 +34,7 @@ export function GenericEditableTextCellEditMode({
|
||||
setFieldValue(newText);
|
||||
|
||||
if (currentRowEntityId && updateField) {
|
||||
updateField(currentRowEntityId, fieldName, newText);
|
||||
updateField(currentRowEntityId, viewFieldId, newText);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user