Removing Prisma and Grapql-nestjs-prisma resolvers (#2574)

* Some cleaning

* Fix seeds

* Fix all sign in, sign up flow and apiKey optimistic rendering

* Fix
This commit is contained in:
Charles Bochet
2023-11-19 18:25:47 +01:00
committed by GitHub
parent 18dac1a2b6
commit f5e1d7825a
616 changed files with 2220 additions and 23073 deletions

View File

@ -30,6 +30,7 @@ const meta: Meta = {
fieldMetadataId: 'date',
label: 'Date',
type: 'DATE',
iconName: 'IconCalendarEvent',
metadata: {
fieldName: 'Date',
},

View File

@ -29,6 +29,7 @@ const meta: Meta = {
fieldMetadataId: 'email',
label: 'Email',
type: 'EMAIL',
iconName: 'IconLink',
metadata: {
fieldName: 'Email',
placeHolder: 'Email',

View File

@ -28,6 +28,7 @@ const meta: Meta = {
fieldDefinition: {
fieldMetadataId: 'enum',
label: 'Enum',
iconName: 'IconTag',
type: 'ENUM',
metadata: {
fieldName: 'Enum',

View File

@ -28,6 +28,7 @@ const meta: Meta = {
fieldMetadataId: 'money',
label: 'Money',
type: 'MONEY_AMOUNT',
iconName: 'Icon123',
metadata: {
fieldName: 'Amount',
placeHolder: 'Amount',

View File

@ -28,6 +28,7 @@ const meta: Meta = {
fieldMetadataId: 'number',
label: 'Number',
type: 'NUMBER',
iconName: 'Icon123',
metadata: {
fieldName: 'Number',
placeHolder: 'Number',

View File

@ -29,6 +29,7 @@ const meta: Meta = {
fieldMetadataId: 'phone',
label: 'Phone',
type: 'PHONE',
iconName: 'IconPhone',
metadata: {
fieldName: 'Phone',
placeHolder: 'Phone',

View File

@ -28,6 +28,7 @@ const meta: Meta = {
fieldMetadataId: 'text',
label: 'Text',
type: 'TEXT',
iconName: 'IconLink',
metadata: {
fieldName: 'Text',
placeHolder: 'Text',

View File

@ -29,6 +29,7 @@ const meta: Meta = {
fieldMetadataId: 'URL',
label: 'URL',
type: 'URL',
iconName: 'IconLink',
metadata: {
fieldName: 'URL',
placeHolder: 'URL',

View File

@ -4,7 +4,7 @@ import styled from '@emotion/styled';
import { CompanyPicker } from '@/companies/components/CompanyPicker';
import { PeoplePicker } from '@/people/components/PeoplePicker';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { UserPicker } from '@/users/components/UserPicker';
import { WorkspaceMemberPicker } from '@/workspace-member/components/WorkspaceMemberPicker';
import { usePersistField } from '../../../hooks/usePersistField';
import { useRelationField } from '../../hooks/useRelationField';
@ -48,7 +48,7 @@ export const RelationFieldInput = ({
initialSearchFilter={initialSearchValue}
/>
) : fieldDefinition.metadata.fieldName === 'accountOwner' ? (
<UserPicker
<WorkspaceMemberPicker
userId={initialValue?.id ?? ''}
onSubmit={handleSubmit}
onCancel={onCancel}

View File

@ -35,6 +35,7 @@ const BooleanFieldInputWithContext = ({
fieldDefinition={{
fieldMetadataId: 'boolean',
label: 'Boolean',
iconName: 'Icon123',
type: 'BOOLEAN',
metadata: {
fieldName: 'Boolean',

View File

@ -47,6 +47,7 @@ const ChipFieldInputWithContext = ({
fieldMetadataId: 'chip',
label: 'Chip',
type: 'CHIP',
iconName: 'Icon123',
metadata: {
contentFieldName: 'name',
urlFieldName: 'xURL',

View File

@ -46,6 +46,7 @@ const DateFieldInputWithContext = ({
fieldMetadataId: 'date',
label: 'Date',
type: 'DATE',
iconName: 'IconCalendarEvent',
metadata: {
fieldName: 'Date',
},

View File

@ -60,6 +60,7 @@ const DoubleTextChipFieldInputWithContext = ({
fieldMetadataId: 'double-text-chip',
label: 'Double-Text-Chip',
type: 'DOUBLE_TEXT_CHIP',
iconName: 'IconUser',
metadata: {
firstValueFieldName: 'First-text',
firstValuePlaceholder: 'First-text',

View File

@ -46,6 +46,7 @@ const EmailFieldInputWithContext = ({
fieldMetadataId: 'email',
label: 'Email',
type: 'EMAIL',
iconName: 'IconLink',
metadata: {
fieldName: 'email',
placeHolder: 'username@email.com',

View File

@ -46,6 +46,7 @@ const MoneyFieldInputWithContext = ({
fieldMetadataId: 'moneyAmount',
label: 'MoneyAmout',
type: 'MONEY_AMOUNT',
iconName: 'Icon123',
metadata: {
fieldName: 'moneyAmount',
placeHolder: 'Enter Amount',

View File

@ -45,6 +45,7 @@ const NumberFieldInputWithContext = ({
fieldDefinition={{
fieldMetadataId: 'number',
label: 'Number',
iconName: 'Icon123',
type: 'NUMBER',
metadata: {
fieldName: 'number',

View File

@ -46,6 +46,7 @@ const PhoneFieldInputWithContext = ({
fieldMetadataId: 'phone',
label: 'Phone',
type: 'PHONE',
iconName: 'IconPhone',
metadata: {
fieldName: 'Phone',
placeHolder: 'Enter phone number',

View File

@ -44,6 +44,7 @@ const ProbabilityFieldInputWithContext = ({
fieldMetadataId: 'probability',
label: 'Probability',
type: 'PROBABILITY',
iconName: 'Icon123',
metadata: {
fieldName: 'Probability',
},

View File

@ -49,6 +49,7 @@ const RelationFieldInputWithContext = ({
fieldMetadataId: 'relation',
label: 'Relation',
type: 'RELATION',
iconName: 'IconLink',
metadata: {
fieldName: 'Relation',
relationType: Entity.Person,

View File

@ -46,6 +46,7 @@ const TextFieldInputWithContext = ({
fieldMetadataId: 'text',
label: 'Text',
type: 'TEXT',
iconName: 'IconTag',
metadata: {
fieldName: 'Text',
placeHolder: 'Enter text',

View File

@ -46,6 +46,7 @@ const URLFieldInputWithContext = ({
fieldMetadataId: 'url',
label: 'URL',
type: 'URL',
iconName: 'IconLink',
metadata: {
fieldName: 'URL',
placeHolder: 'Enter URL',

View File

@ -1,4 +1,3 @@
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { AvatarType } from '@/users/components/Avatar';
import { FieldMetadata } from './FieldMetadata';
@ -13,7 +12,7 @@ export type FieldDefinitionRelationType =
export type FieldDefinition<T extends FieldMetadata> = {
fieldMetadataId: string;
label: string;
Icon?: IconComponent;
iconName: string;
type: FieldType;
metadata: T;
basePathToShowPage?: string;

View File

@ -9,7 +9,7 @@ export type FieldType =
| 'DOUBLE_TEXT'
| 'EMAIL'
| 'ENUM'
| 'MONEY_AMOUNT_V2'
| 'MONEY_AMOUNT_'
| 'MONEY_AMOUNT'
| 'MONEY'
| 'NUMBER'

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldBooleanMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldBoolean = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldBooleanMetadata> => field.type === 'BOOLEAN';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldChipMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldChip = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldChipMetadata> => field.type === 'CHIP';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldCurrencyMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldCurrency = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldCurrencyMetadata> => field.type === 'CURRENCY';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldDateMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldDate = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldDateMetadata> => field.type === 'DATE';

View File

@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldDoubleTextMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldDoubleText = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldDoubleTextMetadata> =>
field.type === 'DOUBLE_TEXT';

View File

@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldDoubleTextChipMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldDoubleTextChip = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldDoubleTextChipMetadata> =>
field.type === 'DOUBLE_TEXT_CHIP';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldEmailMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldEmail = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldEmailMetadata> => field.type === 'EMAIL';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldEnumMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldEnum = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldEnumMetadata> => field.type === 'ENUM';

View File

@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldCurrencyMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldFullName = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldCurrencyMetadata> =>
field.type === 'FULL_NAME';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldLinkMetadata, FieldMetadata } from '../FieldMetadata';
export const isFieldLink = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldLinkMetadata> => field.type === 'LINK';

View File

@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldMoneyMetadata } from '../FieldMetadata';
export const isFieldMoney = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldMoneyMetadata> =>
field.type === 'MONEY_AMOUNT';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldNumberMetadata } from '../FieldMetadata';
export const isFieldNumber = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldNumberMetadata> => field.type === 'NUMBER';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldPhoneMetadata } from '../FieldMetadata';
export const isFieldPhone = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldPhoneMetadata> => field.type === 'PHONE';

View File

@ -2,6 +2,6 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldProbabilityMetadata } from '../FieldMetadata';
export const isFieldProbability = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldProbabilityMetadata> =>
field.type === 'PROBABILITY';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldRelationMetadata } from '../FieldMetadata';
export const isFieldRelation = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldRelationMetadata> => field.type === 'RELATION';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldTextMetadata } from '../FieldMetadata';
export const isFieldText = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldTextMetadata> => field.type === 'TEXT';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldURLMetadata } from '../FieldMetadata';
export const isFieldURL = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldURLMetadata> => field.type === 'URL';

View File

@ -2,5 +2,5 @@ import { FieldDefinition } from '../FieldDefinition';
import { FieldMetadata, FieldUuidMetadata } from '../FieldMetadata';
export const isFieldUuid = (
field: FieldDefinition<FieldMetadata>,
field: Pick<FieldDefinition<FieldMetadata>, 'type'>,
): field is FieldDefinition<FieldUuidMetadata> => field.type === 'UUID';

View File

@ -1,3 +1,4 @@
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
@ -14,6 +15,8 @@ export const ObjectFilterDropdownFilterSelect = () => {
availableFilterDefinitions,
} = useFilter();
const { icons } = useLazyLoadIcons();
const setHotkeyScope = useSetHotkeyScope();
return (
@ -35,7 +38,7 @@ export const ObjectFilterDropdownFilterSelect = () => {
setObjectFilterDropdownSearchInput('');
}}
LeftIcon={availableFilterDefinition.Icon}
LeftIcon={icons[availableFilterDefinition.iconName]}
text={availableFilterDefinition.label}
/>
))}

View File

@ -5,7 +5,7 @@ import { FilterType } from './FilterType';
export type FilterDefinition = {
fieldMetadataId: string;
label: string;
Icon: IconComponent;
iconName: string;
type: FilterType;
entitySelectComponent?: JSX.Element;
selectAllLabel?: string;

View File

@ -1,111 +0,0 @@
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { QueryMode } from '~/generated/graphql';
import { Filter } from '../types/Filter';
type FilterToTurnIntoWhereClause = Omit<Filter, 'definition'> & {
definition: {
type: Filter['definition']['type'];
};
};
export const turnFilterIntoWhereClause = (
filter: FilterToTurnIntoWhereClause | undefined,
) => {
if (!filter) {
return {};
}
switch (filter.operand) {
case ViewFilterOperand.IsNotNull:
return {
[filter.fieldMetadataId]: {
not: null,
},
};
default:
switch (filter.definition.type) {
case 'TEXT':
switch (filter.operand) {
case ViewFilterOperand.Contains:
return {
[filter.fieldMetadataId]: {
contains: filter.value,
mode: QueryMode.Insensitive,
},
};
case ViewFilterOperand.DoesNotContain:
return {
[filter.fieldMetadataId]: {
not: {
contains: filter.value,
mode: QueryMode.Insensitive,
},
},
};
default:
throw new Error(
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
);
}
case 'NUMBER':
switch (filter.operand) {
case ViewFilterOperand.GreaterThan:
return {
[filter.fieldMetadataId]: {
gte: parseFloat(filter.value),
},
};
case ViewFilterOperand.LessThan:
return {
[filter.fieldMetadataId]: {
lte: parseFloat(filter.value),
},
};
default:
throw new Error(
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
);
}
case 'DATE':
switch (filter.operand) {
case ViewFilterOperand.GreaterThan:
return {
[filter.fieldMetadataId]: {
gte: filter.value,
},
};
case ViewFilterOperand.LessThan:
return {
[filter.fieldMetadataId]: {
lte: filter.value,
},
};
default:
throw new Error(
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
);
}
case 'ENTITY':
switch (filter.operand) {
case ViewFilterOperand.Is:
return {
[filter.fieldMetadataId]: {
equals: filter.value,
},
};
case ViewFilterOperand.IsNot:
return {
[filter.fieldMetadataId]: {
not: { equals: filter.value },
},
};
default:
throw new Error(
`Unknown operand ${filter.operand} for ${filter.definition.type} filter`,
);
}
default:
throw new Error('Unknown filter type');
}
}
};

View File

@ -1,13 +0,0 @@
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { SortOrder as Order_By } from '~/generated/graphql';
export type SortType<OrderByTemplate> = {
label: string;
key: string;
Icon?: IconComponent;
orderByTemplate?: (order: Order_By) => OrderByTemplate[];
};
export type SelectedSortType<OrderByTemplate> = SortType<OrderByTemplate> & {
order: 'asc' | 'desc';
};

View File

@ -1,16 +0,0 @@
import { SortOrder as Order_By } from '~/generated/graphql';
import { Sort } from '../types/Sort';
export const reduceSortsToOrderBy = (sorts: Sort[]): any[] =>
sorts
.map((sort) => {
const direction = sort.direction === 'asc' ? Order_By.Asc : Order_By.Desc;
if (sort.definition.getOrderByTemplate) {
return sort.definition.getOrderByTemplate(direction);
} else {
return [{ [sort.definition.fieldMetadataId]: direction }];
}
})
.flat();

View File

@ -1,5 +1,6 @@
import { useContext } from 'react';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { FieldDisplay } from '../../field/components/FieldDisplay';
@ -58,6 +59,8 @@ export const RecordInlineCell = () => {
closeInlineCell();
};
const { icons } = useLazyLoadIcons();
return (
<RecordInlineCellContainer
buttonIcon={buttonIcon}
@ -68,7 +71,7 @@ export const RecordInlineCell = () => {
}
: undefined
}
IconLabel={fieldDefinition.Icon}
IconLabel={icons[fieldDefinition.iconName]}
editModeContent={
<FieldInput
onEnter={handleEnter}

View File

@ -1,6 +1,7 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
import { ColumnDefinition } from '../types/ColumnDefinition';
@ -38,11 +39,14 @@ const StyledText = styled.span`
export const ColumnHead = ({ column }: ColumnHeadProps) => {
const theme = useTheme();
const { icons, isLoadingIcons } = useLazyLoadIcons();
const Icon = icons[column.iconName];
return (
<>
<StyledTitle>
<StyledIcon>
{column.Icon && <column.Icon size={theme.icon.size.md} />}
{!isLoadingIcons && <Icon size={theme.icon.size.md} />}
</StyledIcon>
<StyledText>{column.label}</StyledText>
</StyledTitle>

View File

@ -1,32 +0,0 @@
import { useRecoilValue } from 'recoil';
import { RowIdContext } from '../contexts/RowIdContext';
import { RowIndexContext } from '../contexts/RowIndexContext';
import { isFetchingRecordTableDataState } from '../states/isFetchingRecordTableDataState';
import { tableRowIdsState } from '../states/tableRowIdsState';
import { RecordTableRow } from './RecordTableRow';
export const RecordTableBodyV1 = () => {
const tableRowIds = useRecoilValue(tableRowIdsState);
const isFetchingRecordTableData = useRecoilValue(
isFetchingRecordTableDataState,
);
if (isFetchingRecordTableData) {
return <></>;
}
return (
<tbody>
{tableRowIds.map((rowId, rowIndex) => (
<RowIdContext.Provider value={rowId} key={rowId}>
<RowIndexContext.Provider value={rowIndex}>
<RecordTableRow key={rowId} rowId={rowId} />
</RowIndexContext.Provider>
</RowIdContext.Provider>
))}
</tbody>
);
};

View File

@ -1,73 +0,0 @@
import { useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import defaults from 'lodash/defaults';
import { useRecoilValue } from 'recoil';
import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimisticEffect';
import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition';
import {
SortOrder,
useGetCompaniesQuery,
useGetPeopleQuery,
} from '~/generated/graphql';
import { FilterDefinition } from '../../object-filter-dropdown/types/FilterDefinition';
import { SortDefinition } from '../../object-sort-dropdown/types/SortDefinition';
import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
import { useRecordTable } from '../hooks/useRecordTable';
export const RecordTableEffect = ({
useGetRequest,
getRequestResultKey,
getRequestOptimisticEffectDefinition,
setActionBarEntries,
setContextMenuEntries,
}: {
useGetRequest: typeof useGetCompaniesQuery | typeof useGetPeopleQuery;
getRequestResultKey: string;
getRequestOptimisticEffectDefinition: OptimisticEffectDefinition;
filterDefinitionArray: FilterDefinition[];
sortDefinitionArray: SortDefinition[];
setActionBarEntries?: () => void;
setContextMenuEntries?: () => void;
}) => {
const { setRecordTableData } = useRecordTable();
const { tableSortsOrderBySelector, tableFiltersWhereSelector } =
useRecordTableScopedStates();
const { registerOptimisticEffect } = useOptimisticEffect({
objectNameSingular: 'companyV2',
});
const tableSortsOrderBy = useRecoilValue(tableSortsOrderBySelector);
const sortsOrderBy = defaults(tableSortsOrderBy, [
{
createdAt: SortOrder.Desc,
},
]);
const tableFiltersWhere = useRecoilValue(tableFiltersWhereSelector);
useGetRequest({
variables: { orderBy: sortsOrderBy, where: tableFiltersWhere },
onCompleted: (data: any) => {
const entities = data[getRequestResultKey] ?? [];
setRecordTableData(entities);
registerOptimisticEffect({
variables: { orderBy: sortsOrderBy, where: tableFiltersWhere },
definition: getRequestOptimisticEffectDefinition,
});
},
});
const [searchParams] = useSearchParams();
useEffect(() => {
setActionBarEntries?.();
setContextMenuEntries?.();
}, [searchParams, setActionBarEntries, setContextMenuEntries]);
return <></>;
};

View File

@ -2,6 +2,7 @@ import { useCallback } from 'react';
import { useRecoilValue } from 'recoil';
import { IconPlus } from '@/ui/display/icon';
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
@ -18,6 +19,8 @@ export const RecordTableHeaderPlusButtonContent = () => {
const hiddenTableColumns = useRecoilValue(hiddenTableColumnsSelector);
const { icons } = useLazyLoadIcons();
const { handleColumnVisibilityChange } = useTableColumns();
const handleAddColumn = useCallback(
@ -39,7 +42,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
onClick: () => handleAddColumn(column),
},
]}
LeftIcon={column.Icon}
LeftIcon={icons[column.iconName]}
text={column.label}
/>
))}

View File

@ -1,146 +0,0 @@
import { useRef } from 'react';
import styled from '@emotion/styled';
import { DragSelect } from '@/ui/utilities/drag-select/components/DragSelect';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import {
useListenClickOutside,
useListenClickOutsideByClassName,
} from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { EntityUpdateMutationContext } from '../contexts/EntityUpdateMutationHookContext';
import { useRecordTable } from '../hooks/useRecordTable';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { RecordTableBodyV1 } from './RecordTableBodyV1';
import { RecordTableHeader } from './RecordTableHeader';
const StyledTable = styled.table`
border-collapse: collapse;
border-radius: ${({ theme }) => theme.border.radius.sm};
border-spacing: 0;
margin-left: ${({ theme }) => theme.table.horizontalCellMargin};
margin-right: ${({ theme }) => theme.table.horizontalCellMargin};
table-layout: fixed;
width: calc(100% - ${({ theme }) => theme.table.horizontalCellMargin} * 2);
th {
border: 1px solid ${({ theme }) => theme.border.color.light};
border-collapse: collapse;
color: ${({ theme }) => theme.font.color.tertiary};
padding: 0;
text-align: left;
:last-child {
border-right-color: transparent;
}
:first-of-type {
border-left-color: transparent;
border-right-color: transparent;
}
:last-of-type {
width: 100%;
}
}
td {
border: 1px solid ${({ theme }) => theme.border.color.light};
border-collapse: collapse;
color: ${({ theme }) => theme.font.color.primary};
padding: 0;
text-align: left;
:last-child {
border-right-color: transparent;
}
:first-of-type {
border-left-color: transparent;
border-right-color: transparent;
}
}
`;
const StyledTableWithHeader = styled.div`
display: flex;
flex: 1;
flex-direction: column;
width: 100%;
`;
const StyledTableContainer = styled.div`
display: flex;
flex-direction: column;
height: 100%;
overflow: auto;
position: relative;
`;
type RecordTableV1Props = {
updateEntityMutation: (params: any) => void;
};
export const RecordTableV1 = ({ updateEntityMutation }: RecordTableV1Props) => {
const tableBodyRef = useRef<HTMLDivElement>(null);
const {
leaveTableFocus,
setRowSelectedState,
resetTableRowSelection,
useMapKeyboardToSoftFocus,
getIsSomeCellInEditMode,
} = useRecordTable();
useMapKeyboardToSoftFocus();
useListenClickOutside({
refs: [tableBodyRef],
callback: () => {
leaveTableFocus();
},
});
useScopedHotkeys(
'escape',
() => {
resetTableRowSelection();
},
TableHotkeyScope.Table,
);
useListenClickOutsideByClassName({
classNames: ['entity-table-cell'],
excludeClassNames: ['action-bar', 'context-menu'],
callback: () => {
resetTableRowSelection();
},
});
const handleMouseLeave = () => {
const isSomeCellInEditMode = getIsSomeCellInEditMode();
if (isSomeCellInEditMode) return;
leaveTableFocus();
};
return (
<EntityUpdateMutationContext.Provider value={updateEntityMutation}>
<StyledTableWithHeader>
<StyledTableContainer>
<div ref={tableBodyRef} onMouseLeave={handleMouseLeave}>
<StyledTable className="entity-table-cell">
<RecordTableHeader />
<RecordTableBodyV1 />
</StyledTable>
<DragSelect
dragSelectable={tableBodyRef}
onDragSelectionStart={resetTableRowSelection}
onDragSelectionChange={setRowSelectedState}
/>
</div>
</StyledTableContainer>
</StyledTableWithHeader>
</EntityUpdateMutationContext.Provider>
);
};

View File

@ -17,8 +17,6 @@ export const useRecordTableScopedStates = (args?: {
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableSortsOrderBySelector,
tableFiltersWhereSelector,
tableColumnsState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,
@ -34,8 +32,6 @@ export const useRecordTableScopedStates = (args?: {
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableSortsOrderBySelector,
tableFiltersWhereSelector,
tableColumnsState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,

View File

@ -43,6 +43,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
tableFiltersState,
tableSortsState,
tableColumnsState,
onEntityCountChangeState,
} = useRecordTableScopedStates({
customRecordTableScopeId: scopeId,
});
@ -51,6 +52,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
availableTableColumnsState,
);
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
const setTableFilters = useSetRecoilState(tableFiltersState);
const setTableSorts = useSetRecoilState(tableSortsState);
@ -299,6 +301,7 @@ export const useRecordTable = (props?: useRecordTableProps) => {
setAvailableTableColumns,
setTableFilters,
setTableSorts,
setOnEntityCountChange,
setRecordTableData,
setTableColumns,
leaveTableFocus,

View File

@ -10,27 +10,21 @@ type RecordTableScopeProps = {
children: ReactNode;
recordTableScopeId: string;
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
onEntityCountChange: (entityCount: number) => void;
};
export const RecordTableScope = ({
children,
recordTableScopeId,
onColumnsChange,
onEntityCountChange,
}: RecordTableScopeProps) => {
return (
<RecordTableScopeInternalContext.Provider
value={{
scopeId: recordTableScopeId,
onColumnsChange,
onEntityCountChange,
}}
>
<RecordTableScopeInitEffect
onColumnsChange={onColumnsChange}
onEntityCountChange={onEntityCountChange}
/>
<RecordTableScopeInitEffect onColumnsChange={onColumnsChange} />
{children}
</RecordTableScopeInternalContext.Provider>
);

View File

@ -12,23 +12,14 @@ type RecordTableScopeInitEffectProps = {
export const RecordTableScopeInitEffect = ({
onColumnsChange,
onEntityCountChange,
}: RecordTableScopeInitEffectProps) => {
const { onColumnsChangeState, onEntityCountChangeState } =
useRecordTableScopedStates();
const { onColumnsChangeState } = useRecordTableScopedStates();
const setOnEntityCountChange = useSetRecoilState(onEntityCountChangeState);
const setOnColumnsChange = useSetRecoilState(onColumnsChangeState);
useEffect(() => {
setOnEntityCountChange(() => onEntityCountChange);
setOnColumnsChange(() => onColumnsChange);
}, [
onColumnsChange,
onEntityCountChange,
setOnColumnsChange,
setOnEntityCountChange,
]);
}, [onColumnsChange, setOnColumnsChange]);
return <></>;
};

View File

@ -6,7 +6,6 @@ import { ColumnDefinition } from '../../types/ColumnDefinition';
type RecordTableScopeInternalContextProps = ScopedStateKey & {
onColumnsChange: (columns: ColumnDefinition<FieldMetadata>[]) => void;
onEntityCountChange: (entityCount: number) => void;
};
export const RecordTableScopeInternalContext =

View File

@ -1,18 +0,0 @@
import { selectorFamily } from 'recoil';
import { reduceSortsToOrderBy } from '@/ui/object/object-sort-dropdown/utils/helpers';
import { SortOrder } from '~/generated/graphql';
import { tableSortsScopedState } from '../tableSortsScopedState';
export const tableSortsOrderByScopedSelector = selectorFamily({
key: 'tableSortsOrderByScopedSelector',
get:
(scopeId: string) =>
({ get }) => {
const orderBy = reduceSortsToOrderBy(
get(tableSortsScopedState({ scopeId })),
);
return orderBy.length ? orderBy : [{ createdAt: SortOrder.Desc }];
},
});

View File

@ -1,15 +0,0 @@
import { selectorFamily } from 'recoil';
import { turnFilterIntoWhereClause } from '../../../object-filter-dropdown/utils/turnFilterIntoWhereClause';
import { tableFiltersScopedState } from '../tableFiltersScopedState';
export const tableFiltersWhereScopedSelector = selectorFamily({
key: 'tablefiltersWhereScopedSelector',
get:
(scopeId: string) =>
({ get }) => ({
AND: get(tableFiltersScopedState({ scopeId })).map(
turnFilterIntoWhereClause,
),
}),
});

View File

@ -4,8 +4,6 @@ import { availableTableColumnsScopedState } from '../states/availableTableColumn
import { onColumnsChangeScopedState } from '../states/onColumnsChangeScopedState';
import { hiddenTableColumnsScopedSelector } from '../states/selectors/hiddenTableColumnsScopedSelector';
import { tableColumnsByKeyScopedSelector } from '../states/selectors/tableColumnsByKeyScopedSelector';
import { tableFiltersWhereScopedSelector } from '../states/selectors/tablefiltersWhereScopedSelector';
import { tableSortsOrderByScopedSelector } from '../states/selectors/tableSortsOrderByScopedSelector';
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
import { tableFiltersScopedState } from '../states/tableFiltersScopedState';
@ -33,12 +31,6 @@ export const getRecordTableScopedStates = ({
recordTableScopeId,
);
const tableSortsOrderBySelector =
tableSortsOrderByScopedSelector(recordTableScopeId);
const tableFiltersWhereSelector =
tableFiltersWhereScopedSelector(recordTableScopeId);
const tableColumnsState = getScopedState(
tableColumnsScopedState,
recordTableScopeId,
@ -67,8 +59,6 @@ export const getRecordTableScopedStates = ({
availableTableColumnsState,
tableFiltersState,
tableSortsState,
tableSortsOrderBySelector,
tableFiltersWhereSelector,
tableColumnsState,
tableColumnsByKeySelector,
hiddenTableColumnsSelector,