mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-25 13:02:15 +03:00
Fix filter transform with logic operators (#5269)
Various fixes - Remote objects are read-only for now, we already hide and block most of the write actions but the button that allows you to add a new record in an empty collection was still visible. - CreatedAt is not mandatory on remote objects (at least for now) so it was breaking the show page, it now checks if createdAt exists and is not null before trying to display the human readable format `Added x days ago` - The filters are overwritten in query-runner-args.factory.ts to handle NUMBER field type, this was only working with filters like ``` { "id": { "in": [ 1 ] } ``` but not with more depth such as ``` "and": [ {}, { "id": { "in": [ 1 ] } } ] ``` - Fixes CREATE FOREIGN TABLE raw query which was missing ",".
This commit is contained in:
parent
30ffe0160e
commit
50421863d4
@ -81,6 +81,8 @@ export const RecordTableWithWrappers = ({
|
||||
|
||||
const objectLabel = foundObjectMetadataItem?.labelSingular;
|
||||
|
||||
const isRemote = foundObjectMetadataItem?.isRemote ?? false;
|
||||
|
||||
return (
|
||||
<EntityDeleteContext.Provider value={deleteOneRecord}>
|
||||
<ScrollWrapper>
|
||||
@ -113,25 +115,27 @@ export const RecordTableWithWrappers = ({
|
||||
recordTableId={recordTableId}
|
||||
tableBodyRef={tableBodyRef}
|
||||
/>
|
||||
{!isRecordTableInitialLoading && numberOfTableRows === 0 && (
|
||||
<AnimatedPlaceholderEmptyContainer>
|
||||
<AnimatedPlaceholder type="noRecord" />
|
||||
<AnimatedPlaceholderEmptyTextContainer>
|
||||
<AnimatedPlaceholderEmptyTitle>
|
||||
Add your first {objectLabel}
|
||||
</AnimatedPlaceholderEmptyTitle>
|
||||
<AnimatedPlaceholderEmptySubTitle>
|
||||
Use our API or add your first {objectLabel} manually
|
||||
</AnimatedPlaceholderEmptySubTitle>
|
||||
</AnimatedPlaceholderEmptyTextContainer>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title={`Add a ${objectLabel}`}
|
||||
variant={'secondary'}
|
||||
onClick={createRecord}
|
||||
/>
|
||||
</AnimatedPlaceholderEmptyContainer>
|
||||
)}
|
||||
{!isRecordTableInitialLoading &&
|
||||
numberOfTableRows === 0 &&
|
||||
!isRemote && (
|
||||
<AnimatedPlaceholderEmptyContainer>
|
||||
<AnimatedPlaceholder type="noRecord" />
|
||||
<AnimatedPlaceholderEmptyTextContainer>
|
||||
<AnimatedPlaceholderEmptyTitle>
|
||||
Add your first {objectLabel}
|
||||
</AnimatedPlaceholderEmptyTitle>
|
||||
<AnimatedPlaceholderEmptySubTitle>
|
||||
Use our API or add your first {objectLabel} manually
|
||||
</AnimatedPlaceholderEmptySubTitle>
|
||||
</AnimatedPlaceholderEmptyTextContainer>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title={`Add a ${objectLabel}`}
|
||||
variant={'secondary'}
|
||||
onClick={createRecord}
|
||||
/>
|
||||
</AnimatedPlaceholderEmptyContainer>
|
||||
)}
|
||||
</StyledTableContainer>
|
||||
</StyledTableWithHeader>
|
||||
</RecordUpdateContext.Provider>
|
||||
|
@ -112,7 +112,11 @@ export const ShowPageSummaryCard = ({
|
||||
</StyledAvatarWrapper>
|
||||
<StyledInfoContainer>
|
||||
<StyledTitle>{title}</StyledTitle>
|
||||
<StyledDate id={dateElementId}>Added {beautifiedCreatedAt}</StyledDate>
|
||||
{beautifiedCreatedAt && (
|
||||
<StyledDate id={dateElementId}>
|
||||
Added {beautifiedCreatedAt}
|
||||
</StyledDate>
|
||||
)}
|
||||
<StyledTooltip
|
||||
anchorSelect={`#${dateElementId}`}
|
||||
content={exactCreatedAt}
|
||||
|
@ -131,30 +131,46 @@ export class QueryRunnerArgsFactory {
|
||||
return;
|
||||
}
|
||||
|
||||
const createArgPromiseByArgKey = Object.entries(filter).map(
|
||||
([key, value]) => {
|
||||
const fieldMetadata = fieldMetadataMap.get(key);
|
||||
|
||||
if (!fieldMetadata) {
|
||||
return [key, value];
|
||||
const overrideFilter = (filterObject: RecordFilter) => {
|
||||
return Object.entries(filterObject).reduce((acc, [key, value]) => {
|
||||
if (key === 'and' || key === 'or') {
|
||||
acc[key] = value.map((nestedFilter: RecordFilter) =>
|
||||
overrideFilter(nestedFilter),
|
||||
);
|
||||
} else if (key === 'not') {
|
||||
acc[key] = overrideFilter(value);
|
||||
} else {
|
||||
acc[key] = this.transformValueByType(key, value, fieldMetadataMap);
|
||||
}
|
||||
|
||||
const createFilterByKey = Object.entries(value).map(
|
||||
([filterKey, filterValue]) => {
|
||||
switch (fieldMetadata.type) {
|
||||
case FieldMetadataType.NUMBER:
|
||||
return [filterKey, Number(filterValue)];
|
||||
default:
|
||||
return [filterKey, filterValue];
|
||||
}
|
||||
},
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
return overrideFilter(filter);
|
||||
}
|
||||
|
||||
private transformValueByType(
|
||||
key: string,
|
||||
value: any,
|
||||
fieldMetadataMap: Map<string, FieldMetadataInterface>,
|
||||
) {
|
||||
const fieldMetadata = fieldMetadataMap.get(key);
|
||||
|
||||
if (!fieldMetadata) {
|
||||
return value;
|
||||
}
|
||||
switch (fieldMetadata.type) {
|
||||
case 'NUMBER':
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).map(([filterKey, filterValue]) => [
|
||||
filterKey,
|
||||
Number(filterValue),
|
||||
]),
|
||||
);
|
||||
|
||||
return [key, Object.fromEntries(createFilterByKey)];
|
||||
},
|
||||
);
|
||||
|
||||
return Object.fromEntries(createArgPromiseByArgKey);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private async overrideValueByFieldMetadata(
|
||||
|
@ -495,11 +495,9 @@ export class WorkspaceMigrationRunnerService {
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
let serverOptions = '';
|
||||
|
||||
Object.entries(foreignTable.referencedTable).forEach(([key, value]) => {
|
||||
serverOptions += ` ${key} '${value}'`;
|
||||
});
|
||||
const serverOptions = Object.entries(foreignTable.referencedTable)
|
||||
.map(([key, value]) => `${key} '${value}'`)
|
||||
.join(', ');
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE FOREIGN TABLE ${schemaName}."${name}" (${foreignTableColumns}) SERVER "${foreignTable.foreignDataWrapperId}" OPTIONS (${serverOptions})`,
|
||||
|
Loading…
Reference in New Issue
Block a user